Jan 03, 2019

Implementation Strategies for Distributed Saga pattern


Event-driven/Choreographed

In a event-driven architecture, each service listens to events emitted by other services and perform the required action. Let’s take the example of the trip service:

Trip creation flow

When a user requests for a trip creation, Trip service triggers Trip_Created_Event. The Flight service listens to Trip service for the Trip_Created_Event and books a flight and emits Flight_Booked_Event. Car rental service listens to Flight service for the Flight_Booked_Event and books a cab and emits Car_Rented_Event. Hotel reservation service listens to Car rental service for Car_Rented_Event and makes a hotel reservation and emits Room_Reserved_Event. The Trip service listens for the Room_Reserved_Event and updates the Trip state.

In case we failed to book a hotel room we have to execute compensating requests for canceling car booking and canceling the flight ticket.

Compensating requests execution flow

The Car rental service listens for Reservation_Failed event and executes the compensating cancel car booking request and emits Car_Booking_Cancelled event. The flight service listens for Car_Booking_Cancelled event and executes compensating request to cancel flight ticket and emits Flight_Booking_Cancelled event. The trip service listens for this event and updates the state of the trip.

Advantages

  • It is easy to implement
  • Participants are loosely coupled

Disadvantages

  • Can easily become confusing as the application becomes complex.
  • Difficult to trace the flow without observing the live system.
  • Testing will become tricky as all the services should be running.

Command/Orchestration

In this approach, there is a single service which acts as a coordinator for the whole saga. It knows all the steps involved in executing a saga

Requests execution flow

It sends commands to the required services to book a flight, rent a cab and reserve a hotel room.

In case of failure in either of them, it calls the compensating requests for the successful requests. For example, if we fail to reserve a hotel room:

Compensating requests execution flow

It calls the compensating request for the car rental service and flight service.

Advantages

  • The orchestration of the distributed transactions is centralized
  • Reduce participants complexity as they only need to execute/reply to commands
  • Easier to implement
  • Easier to manage a rollback
  • Easy to add new stages to the Saga

Disadvantages

  • We have to manage an extra service
  • We are making smart architecture and dumb services

Points to keep in mind during implementation

We can design our system in such a way that, we send the response to the trip service once the saga execution is complete

  • Advantage: Response specifies the outcome
  • Disadvantage: Reduce availability as the whole saga has to execute before returning a response

We can design our system to return response as soon as the saga execution starts

  • Advantage: Improved availability
  • Disadvantage: Client must poll or be notified to check the status of the Saga execution.

We have to keep in mind on how to cancel a pending operation

  • Whether to wait for it to succeed and then cancel it.
  • Cancel it and make sure if you get the request late, it is not executed.

We can also use asynchronous messaging to ensure saga completes when participants are temporarily unavailable.

Sai Prasanth NG

System Architecture