Search code examples
masstransitmarten

Switching to MassTransit.Marten, sagas not deleting on completion


I'm implementing a saga for the first time and I have been testing it with an InMemory repository until today, when I switched to using Marten/Postgres.

I found that expiry events that set the state to Final no longer result in the Saga being removed. In my case, I'm conversing with a 3rd party remote system, so I can't get them to send Guid correlation Ids to me, so I'm using their identity details.

Here's the basic setup


public class GroupSaga : SagaStateMachineInstance
{
    public string Partition { get; set; }

    public Guid CorrelationId { get; set; }

    public string CurrentState { get; set; }
}

class CommsTimeoutEvent : ICommsTimeout
{
    readonly GroupSaga _instance;

    public CommsTimeoutEvent(GroupSaga instance)
    {
        _instance = instance;
    }

    public Guid SagaGuid => _instance.CorrelationId;
}

Event(() => MyEventReceived,
            x => x.CorrelateBy(rsp => rsp.Partition, context => context.Message.Partition)
                .SelectId(_ => NewId.NextGuid()));

Schedule(() => CommsTimedOut, x => x.ExpirationId, x =>
        {
            x.Delay = TimeSpan.FromSeconds(10);
            x.Received = e => e.CorrelateById(context => context.Message.SagaGuid);
        });

Initially(
            When(MyEventReceived)
                .Then(context =>
                {
                    context.Saga.Partition = context.Message.Partition;
                })
                .Activity(x => x.OfInstanceType<CustomActivity>())
                .Schedule(CommsTimedOut, context => new CommsTimeoutEvent(context.Saga))
                .TransitionTo(WaitingForResponse));

During(....)

DuringAny(
            When(CommsTimedOut.Received)
                .Finalize());

        SetCompletedWhenFinalized();

If I allow it to timeout, I can see in the database table that the saga has "CurrentState": "Final", but it's never removed and if I launch another event to kick-start the process again, it errors because the initial event isn't handled in state 'Final'.

Have I missed anything? This is all I do to initialse Marten:-

config.AddSagaStateMachine<GroupStateMachine, GroupSaga>()
                .MartenRepository(dbConnectionString);

Solution

  • You need to upgrade to 8.0.7, which adds an Evict call to Marten to ensure it is removed from the database. Prior to this version, the instance would be deleted, followed immediately by an upsert by Marten for whatever reason.