Saga implementation patterns – variations

In the previous couple of posts, I looked at the two main patterns I run into when looking at sagas:

Of course, these aren’t the only ways our saga could behave. We could have any combination of these.

Publish-Gather

Looking back on our McDonald’s example, we could improve our situation a little bit. We could have a situation where we want a command to start a saga, then have the saga itself publish a message. It would then wait for events to come back (ignoring order):

image

The advantage here is that we only have one entry point to our saga. We don’t have to worry about our saga potentially getting started by any number of messages that were pushed out.

When you place an order at McDonald’s, it’s almost always the cashier that places the tray on the table. When stations are finished with fries, sandwiches etc., they don’t really come to the counter and make a decision “do I need a new tray?”. The tray is already there, so our saga has already started.

There’s also nothing stopping our downstream processes from spawning off additional sagas – but that’s hidden from our originator.

Reporter

Another role our saga can play is one that doesn’t make decisions, but instead merely reports status:

image

This is a situation where a saga might never actually complete, and goes on forever. Its role is to communicate status of a longer-running process in the back-end, not for coordination purposes, but for reporting purposes.

The reason we might want a saga for this case is we still don’t know what order we’ve received messages from downstream systems we don’t own. As we learn about downstream events, we can evaluate them based on our knowledge of the overall business process. An order can’t go backwards from “shipped” to “verified”, so receiving these out of order doesn’t change the fact that the order shipped! Note: this doesn’t necessarily imply the status is in the saga entity itself. It still could be separate.

Keeping it as a saga lets us handle messages in any order and keep some centralized logic around interpreting these messages.

Sagas/process managers are pretty flexible in how we compose the pieces together. I often get questions around “why can’t I design a saga like a workflow?” And the answer is that sagas are meant to handle cases where I don’t have a directed workflow, where I live in a world where messages can arrive out of order.

It’s a much easier world to scale – but we need to accept the complexity it brings on the other end.

There is another clear downside here – we have shared state amongst multiple messages and handlers, which can potentially lead to scaling problems. Next time, we’ll look at scaling sagas.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Messaging, NServiceBus, SOA. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • jdn

    Thanks for this Jimmy, this is really good stuff.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1320

  • Alper Sunar

    Just for clarification, when you refer to Sagas are you talking about Sagas as a general concept or Sagas as defined in NServiceBus ecosystem? I’m guessing these patterns can be implemented by a different messaging/service bus system.

    • jbogard

      Good question, I’m using the term Saga to mean NServiceBus saga/ EIP book Process Manager

  • agilejoe

    Your timing on this post is awesome!

  • Pingback: Saga implementation patterns – variations | Jimmy Bogard's Blog | Something interesting | Scoop.it

  • DaMi

    Good article!

  • Colin Dooley

    I think its fair to say that the reporter is in, effect, and in DDD parlance, an aggregate. NSB can be used to augment event sourcing.