One of the reasons that could inhibit the adoption of the Saga Pattern approach - about which you can learn more in this article - is the additional effort caused by the need to implement the resulting system, as there are almost no libraries and ready-to-use components for this purpose.
For this reason, in Mia-Platform we decided to implement a generic component that could act as an orchestrator and could be configured in a simple and intuitive way, according to the specific project.
Which approach we chose
As mentioned, at Mia-Platform we had to face this problem and, consequently, we had to choose which approach best suited our case. Before talking about the chosen approach, however, it is important to briefly introduce the variables that influenced and determined our choice.
Following the initial analysis of the project, we designed a rather complex finite-state machine, which represented exactly all the possible saga flows, that are all the ways in which it could have evolved.
Starting from this automaton, we have identified the various steps of the saga flow and the designated actors - the microservices - to carry on the saga.
At this point there were two approaches available:
- Choreography: microservice call each other;
- Commands/Orchestrator: microservices communicate among themselves and they don’t know each other.
Several factors and needs influenced the choice:
- we knew the flow of the saga wouldn't have been too static, but it would have evolved over time. So we needed a way to make these changes quickly and cleanly;
- we wanted to give a write permission to a single actor;
- we wanted the microservices involved to be extraneous to each other;
- generally, we favour reusable solutions, so we also thought about it when evaluating the most suitable approach.
Given the aforementioned requirements, the choice was simple. We opted for the Commands/Orchestration approach and, since we didn’t find on the web ready-to-use implementations of an orchestrator, we decided to enrich the platform by developing a new component: the Flow Manager.
The solution we have chosen consists of a microservice that manages the sagas following the flow imposed by an event-driven finite-state machine, in which the transitions are triggered by messages. These messages are events exchanged asynchronously via an event bus (e.g. Kafka).
Mia-Platform makes this component available on its platform as an easily deployable and configurable saga orchestrator, fully integrated with the other features of the platform.
Using the Mia-Platform Flow Manager allows you to configure the saga in a few simple steps. In this way it is possible to save time compared to developing a customized solution; moreover, it offers considerable advantages in terms of business logic management, debugging, and flexibility, in the event of evolution or changes in requirements.
The central orchestrator was developed as a platform’s standard service
The advantages are immediately evident. To meet the specific project needs it is sufficient to define the finite state diagram that describes the possible flows of interactions and translate it into a simple configuration file.
Furthermore, it is possible to obtain a simple and clean solution: the entire business logic is concentrated not only in the code of a single service - an intrinsic advantage of the orchestrator approach - but even in a single file.
Using a ready-to-configure and ready-to-release component allowed us to significantly save time on the project. Developing a microservice from scratch that manages communication with the other components, carries on the flow of the saga, and guarantees the necessary robustness has a considerable cost: an extra two months, according to our estimates.
Besides saving resources during development, another advantage that emerged during the UAT was the flexibility of the system in case of changes in requirements.
With our approach, if the business specifications vary, once the actors involved have been prepared, changing the flow only involves a few changes and adaptations, that are:
- editing the isolated logic of the service/services involved;
- editing the orchestrator’s configuration file.
Also, in the event of a single change to the flow, which doesn’t impact the logic, it may be sufficient to change the configuration file, without modifying the code.
Therefore, this avoids having to modify the orchestrator code, recompose the pre-existing flow, apply the change and explicitly manage the aspects of communication with the other services: operations that would have been necessary if we used an ad-hoc implemented orchestrator to manage the specific flow.
For example, if you wanted to add a phase in the saga - let's say the verification of user data - the classic approach would require to modify the code, check where to insert this new step, and modify the entire flow.
Otherwise, with the approach proposed in Mia-Platform, once the actors involved in the change have been prepared, it is sufficient to change a configuration file by adding the new step.
This approach proposes a simplification of the required modification interventions, with a considerable time and resources saving.
Is configuring our saga easy?
With the Flow Manager, everything you need to orchestrate the saga is:
- Adding the flow-manager plugin:
- Describing the flow in the appropriate config map file:
With the gradual abandonment of the monolithic approach and the transition to the world of microservices, sometimes chaotic, the need to maintain control and visibility over everything that happens is becoming more and more pressing.
At Mia-Platform we have addressed this issue also in the context of data updating, data consistency in distributed systems, and full management - even in the event of errors. We discovered and used the Saga Pattern as an optimal solution to manage this problem and enrich the platform.