Корреляция Masstransit Saga от Natural Key не работает

Я хотел бы использовать уникальный природный ключ вместо встроенного Guid CorrelationId в Masstransit Sagas. Однако это, похоже, не очень работает. Если я дважды отправляю событие Initial с одним и тем же значением ключа, в хранилище создаются две саги - ожидается один экземпляр. Тот же сценарий с использованием CorrelationId создает один экземпляр Saga в репозитории.

Есть идеи, почему второй экземпляр Saga создан с тем же ключом, игнорируя оператор корреляции?

Вот краткий пример с модульным тестом:

[TestFixture]
public class SagaTests
{
    [Test]
    public void TestSagaInitialization()
    {
        var testSaga = new TestSaga();
        var testSagaRepository = new InMemorySagaRepository<TestSagaState>();
        var busControl = Bus.Factory.CreateUsingInMemory(
            cfg =>
            {
                cfg.ReceiveEndpoint("test_queue",
                    e =>
                    {
                        e.StateMachineSaga(testSaga, testSagaRepository);
                    });
            });
        busControl.Start();

        busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 1 }).Wait();
        busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 2 }).Wait();
        // Message with same natural key published again
        busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 1 }).Wait();

        // Wait till all messges consumed
        var till = DateTime.Now.AddSeconds(1);
        while (DateTime.Now < till) { System.Threading.Thread.Sleep(50); }

        busControl.Stop();

        var sagaInstances = testSagaRepository.Where(x => x.UniqueNaturalKey == 1).Result.ToList();
        Assert.AreEqual(1, sagaInstances.Count, "Dublicate initial events with same Natural Key value must not create new Saga instance");
    }
}

public class TestSagaState : Automatonymous.SagaStateMachineInstance
{
    public Guid CorrelationId { get; set; }

    public int CurrentState { get; set; }

    public long UniqueNaturalKey { get; set; }
}

public class TestSaga : MassTransitStateMachine<TestSagaState>
{
    public TestSaga()
    {
        InstanceState(x => x.CurrentState);

        Event(() => SagaInitiated, x => x.CorrelateById(state => state.UniqueNaturalKey, context => context.Message.UniqueNaturalKey)
            .SelectId(context => Guid.NewGuid()));

        Initially(
            When(SagaInitiated)
                .Then(context =>
                {
                    context.Instance.UniqueNaturalKey = context.Data.UniqueNaturalKey;
                })
                .TransitionTo(Initiated)
            );
    }

    public State Initiated { get; private set; }
    public Event<TestSagaInitEvent> SagaInitiated { get; private set; }
}

public class TestSagaInitEvent
{
    public long UniqueNaturalKey { get; set; }
}

0 ответов

Другие вопросы по тегам