mr_city
mr_city

Reputation: 1

No new NServiceBus Saga instance is created when another IAmStarted message is run

I couldn't find any similar topic so I am creating new one. I have strange problem which is not how Sagas usually behave.

When I fire two IAmStartedBy messages, then first one creates new Saga instance, but second one always find the first instance... It should create new, because passed correlation id is different, but it uses the first one instead... Even if first one is Marked as Complete, the second message still finds that completed instance only... Is there a setting, which prevents more than 1 instance created?

public class SimpleSaga : SqlSaga<SimpleSagaData>,
    IAmStartedByMessages<StartProcessingSimpleSagaCommand>,
    IHandleMessages<EndSimpleSagaCommand>
{

    protected override string CorrelationPropertyName => nameof(SimpleSagaData.ProcessId);

    protected override void ConfigureMapping(IMessagePropertyMapper mapper)
    {
        mapper.ConfigureMapping<StartProcessingSimpleSagaCommand>(c => c.ProcessId);
        mapper.ConfigureMapping<EndSimpleSagaCommand>(c => c.ProcessId);
    }

    public async Task Handle(StartProcessingSimpleSagaCommand message, IMessageHandlerContext context)
    {
        if (string.IsNullOrWhiteSpace(Data.ProcessId))
        {
            Data.ProcessId = message.ProcessId;
        }
        else if (Data.ProcessId != message.ProcessId)
        {
            throw new Exception("Only one Saga per ProcessId is allowed!");
        }

        //Sends another message with ProcessId, which will send back EndSimpleSagaCommand with the same ProcessId
    }

    public async Task Handle(EndSimpleSagaCommand message, IMessageHandlerContext context)
    {
        if (Data.ProcessId != message.ProcessId)
        {
            throw new Exception("Saga does not match!");
        }

        MarkAsComplete();
    }
}

Configuration:

        var persistence = endpointConfiguration.UsePersistence<SqlPersistence>();

        var dialect = persistence.SqlDialect<SqlDialect.MsSqlServer>();
        dialect.Schema("nsb");
        persistence.ConnectionBuilder(connectionBuilder: () => new SqlConnection(ConnectionString));

        persistence.TablePrefix("");

        var subscriptions = persistence.SubscriptionSettings();
        subscriptions.CacheFor(TimeSpan.FromMinutes(1));

        endpointConfiguration.EnableFeature<TimeoutManager>();
        endpointConfiguration.SendFailedMessagesTo($"{OwnEndpointName}.errors");
        endpointConfiguration.AssemblyScanner().ExcludeAssemblies("tools");

        endpointConfiguration.LimitMessageProcessingConcurrencyTo(1);

        ConfigureUnobtrusiveMessageConvention(endpointConfiguration);

        endpointConfiguration.Recoverability().Delayed(DelayedSettings);

Simple test which is failing to prove that I am sending two different ProcessId's:

    [Test]
    public async Task Test()
    {

        var startCommand = new StartProcessingSimpleSagaCommand
        {
            ProcessId = "OneReg1"
        };

        var startCommand2 = new StartProcessingSimpleSagaCommand
        {
            ProcessId = "OneReg2"
        };

        await _simpleSaga.Handle(startCommand, _messageContext)
            .ConfigureAwait(false);

        await _simpleSaga.Handle(startCommand2, _messageContext)
            .ConfigureAwait(false);
    }

I will always get one of exceptions... Anyone can help?

Upvotes: 0

Views: 60

Answers (0)

Related Questions