Ryan Durham
Ryan Durham

Reputation: 331

Masstransit Sagas - Events not publishing

Trying to get a saga setup using MT and Automatonymous however something is not clicking and the documentation is slim and it's not clear what's incorrect in my configuration.

I can see the queue for the bus get generated and then the topics for the state machine. However, when I publish an event nothing happens. No exception and nothing in the queue or topics.

Setup and registration:

        var repository = new InMemorySagaRepository<MyObJect>();
        var _machine = new MyStateMachine();

        var _busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
       {
           var host = cfg.Host("omitted", h => { });

           cfg.UseSerilog(logger);

           cfg.ReceiveEndpoint(host, "test", e =>
           {
               e.StateMachineSaga(_machine, repository);
           });
           cfg.UseServiceBusMessageScheduler();
       });

        _busControl.Start();

State Machine:

public class MyStateMachine:
        MassTransitStateMachine<MyObJect>
{
    public MyStateMachine()
    {
        InstanceState(x => x.CurrentState);

        this.Event(() => this.ItemAdded, x => x.CorrelateById(c => c.Message.CorrelationId).SelectId(c => c.Message.CorrelationId));
        this.Event(() => this.ItemSubmitted, x => x.CorrelateById(c => c.Message.CorrelationId));

        Initially(
            When(ItemAdded)
            .ThenAsync(context =>
            {
                return context.Data.AddItem();
                //Update everything you need to on the current instance of the state machine
            })
            .TransitionTo(Added)
            );

        During(Added,
            When(ItemSubmitted)
            .Then(ct => ct.Data.SubmitItem())
            .TransitionTo(Submitted)
            .Finalize()
            );

        SetCompletedWhenFinalized();
    }

    public Event<ItemAdded> ItemAdded { get; private set; }

    public Event<ItemSubmitted> ItemSubmitted { get; private set; }

    public State Added { get; private set; }

    public State Submitted { get; private set; }
}

public class ItemSubmitted
{
    public string ItemId { get; set; }
    public string EntityId { get; set; }
    public System.Guid CorrelationId { get; set; }

    public void SubmitItem()
    {
        System.Threading.Thread.Sleep(30000);
        Console.WriteLine("Submitted the item");
    }
}

public class ItemAdded
{
    public string ItemId { get; set; }
    public string EntityId { get; set; }
    public System.Guid CorrelationId { get; set; }

    public Task AddItem()
    {
        return Task.FromResult(true);
    }
}

StateMachine Instance:

public class MyObJect: SagaStateMachineInstance
{
    public string CurrentState { get; set; }
    public string EntityId { get; set; }
    public string ItemId { get; set; }
    public Guid CorrelationId { get; set; }
}

Publishing events via:

_busControl.Publish<MyObJect>(new MyObJect { EntityId = "123", ItemId = "435", CorrelationId = Guid.NewGuid() }).Wait();

excuse the bad code and contrived examples - I boiled this away into a little harness to wrap my head around it easier

Upvotes: 2

Views: 1349

Answers (1)

Alexey Zimarev
Alexey Zimarev

Reputation: 19610

You seem to misunderstand what saga state is. The saga state is the state of your state machine. It contains the data for your process and it gets persisted to the database.

You need messages to drive your saga and this is what you need to define using

public Event<ItemAdded> ItemAdded { get; private set; }

If you want to start the saga by the ItemAdded event and continue when it receives the ItemSubmitted event, you need to publish ItemAdded. MyObject is the saga state, not a message type.

Upvotes: 1

Related Questions