0

我想使用唯一的自然键而不是在 Masstransit Sagas 中构建 Guid CorrelationId。但是,它似乎并没有真正起作用。如果我发送两次具有相同键值的初始事件,则在存储库中创建两个 Sagas - 预期是单个实例。使用 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; }
}
4

0 回答 0