Search code examples
masstransit

Use MassTransit Activity or Consumer


I'm building a service that will act as layer of abstraction in front an external API which is unreliable. The layer of abstraction will provide resilience, ensuring commands are eventually if the event of an outage. Later, it will provide caching for queries.

We're using MassTransit within the new service to orchestrate the calls to the external API. MT also provides retries, circuit-breaker, throttling etc.

I'd like some advice on when to use MassTransit's Activities vs Consumers from within a StateMachine. There are three scenarios I'd like to consider:

  1. Requesting a resource from the the external API from within a State Machine. We need to handle success, failure, timeouts. It seems obvious to use a Request-Response Consumer here.

  2. Sending a command to the external API from within a State Machine. We need to handle success, failure, retries. We also need retries, throttling, kill-switch to handle outages. Is an Activity the better choice here?

  3. Sending a command from one State Machine to interact with another. We need to handle success, failure, retries. Is a command handled by a different State Machine appropriate here?

Thanks in advice

I currently have a mixture of Consumers and Activities. Both approaches work well. However, at present I'm only using in-memory; I haven't yet considered concurrency.

So, while the approaches I've tried work well in happy-path situations, I'm more interested to know the benefits of each approach when concurrency is considered and, to a lesser degree, what is the more semantically correct approach.

Note, the third party doesn't provide DELETE endpoints so, at present, there are no compensating actions in the event of an error.


Solution

    1. Consumer
    2. Consumer
    3. Activity, or use Publish / Send as appropriate

    In case 3, you can look at how MassTransit uses multiple state machines for the job service and how they collaborate.

    Consumers should be used for 1 and 2 as their execution time is non-deterministic and sagas execute within a database transaction typically.