Joel
Joel

Reputation: 8948

Simplify setup for MassTransit Saga in Azure Service Bus

I'm trying to figure out how to set up a MassTransit saga and minimize the complexity of the setup in Azure Service Bus.

The flow I'm thinking of is this:

  1. Someone sends a command like CreateSaga. It will be sent to a queue called my-saga-queue and be consumed by the saga.
  2. Based on this, the saga will produce some other commands, like DoSomething, that are picked up by consumers elsewhere (not saga specific).
  3. Those consumers will publish events like SomethingIsDone when they are done.
  4. The saga should consume those events and react based on them.

Step 4 is where I'm having some issues figuring out what to do. The SomethingIsDone events can't be published directly to my-saga-queue I guess (since it's a queue), so they have to end up in a subscription on the topic for the event.

But can the saga instance consume from that subscription, or does there have to be a forward from the subscription to a queue?

Some background context: We're trying to simplify our ASB setup with the hope that this will increase our throughput (having some issues with that). Things we're trying to get rid of are things like forwarding between subscriptions and queues, since subscriptions are basically queues in themselves).

Upvotes: 0

Views: 696

Answers (1)

Chris Patterson
Chris Patterson

Reputation: 33268

You could manually configure the initial queue, along with the subscription endpoints, configuring the saga on each endpoint using the same saga repository. It's more work, and tightly couples the bus configuration to each event consumed by the saga, but it is possible using a mix of receive endpoints and subscription endpoints.

For instance, if you had a CartStateMachine with a CartState, you could configure each event similar to:

cfg.SubscriptionEndpoint<CartItemAdded>("cart-state-machine", endpoint =>
{
    endpoint.ConfigureSaga<CartState>(context);
});

cfg.SubscriptionEndpoint<CartItemRemoved>("cart-state-machine", endpoint =>
{
    endpoint.ConfigureSaga<CartState>(context);
});

Then, the actual queue (receive endpoint) for the initial command would be:

configurator.ReceiveEndpoint("cart-state", endpoint =>
{
    endpoint.ConfigureConsumeTopology = false;
    
    endpoint.Subscribe<CreateCart>("cart-state");
    
    endpoint.ConfigureSaga<CartState>(context);
});

You would still add the saga state machine to the container as usual:

services.AddMassTransit(x =>
{
    x.AddSagaStateMachine<CartStateMachine, CartState>()
        .InMemoryRepository();

    x.UsingAzureServiceBus((context, cfg) => 
    {
        // bus configuration
    });
});

Upvotes: 2

Related Questions