1

I'm having some trouble understanding how Finalize() works in MassTransit, and specifically whether it can be executed during the initial state. Setup:

public Event<ICrawlRequestCreated> CrawlCreated { get; private set; }
public Event CrawlFailed { get; private set; }

public State Executing { get; private set; }
public State Completed { get; private set; }
public State Failed { get; private set; }

public WorkflowSaga()
{
    InstanceState(x => x.CurrentState);

    Initially(
        When(CrawlCreated)
            .Then(HandleCrawlRequestCreated)
            .TransitionTo(Executing),
        When(CrawlFailed)
            .Then(HandleCrawlFailed)
            .TransitionTo(Failed)
            .Finalize()
    );

    ...

    SetCompletedWhenFinalized();
}

If I catch an exception in HandleCrawlRequestCreated, I raise CrawlFailed, like so:

context.Raise(CrawlFailed);

which fires HandleCrawlFailed correctly, but it doesn't remove the state machine instance from the repository (SQL Server via EF). But if I raise CrawlFailed during the executing state, the instance is removed from the repository. What am I missing?

LandonC
  • 889
  • 1
  • 16
  • 28

1 Answers1

3

You should use the .Catch() methods, instead of catching the exception in your method, and within the .Catch you can finalize instead of transitioning to the Executing state.

If you Finalize in Initial, it shouldn't ever persist the state machine to the database, but I didn't write the EF repository and I'm not sure the test coverage ensures that to be the case.

Chris Patterson
  • 28,659
  • 3
  • 47
  • 59
  • It seems that saga instance is only added to the context if not completed already. But the next line can also be taken inside the if: https://github.com/MassTransit/MassTransit/blob/0ac2564e0225ff11b6f20f38a18d3b886cc2d7d3/src/Persistence/MassTransit.EntityFrameworkIntegration/Saga/EntityFrameworkSagaRepository.cs#L407 – Alexey Zimarev Aug 24 '17 at 07:39
  • Hey Chris, I was wondering is it even possible to `Finalize` within the `Catch` method? It seems that there's no `Finalize` method for `ExceptionActivityBinder` in the `TransistionExtensions`, only for `EventActivityBinder` and no way of getting the `EventActivityBinder` in the `Catch` method. – Slowacki Nov 09 '17 at 11:43
  • It's likely an extension methods just needs to be added. It's perfectly legal to transition to the `Final` state in a catch block, I'm sure I just didn't think to add it. – Chris Patterson Nov 13 '17 at 16:46