Hi Oleg,
the reason why events related to a specific Saga instance should be processed by the same node is to respect the saga nature.
This is the short answer. ;-)
The long answer is that a Saga is a stateful event consumer with its own
life cycle. Each time a new event is forwarded to the pertaining saga instance, its internal state (of the saga) needs to be rebuilt to let the saga handle the event properly.
Saga Infrastructure, in its various implementations, works to manage this life cycle smoothly using, if necessary, batching and caching to improve the overall performances.
In a distributed environment, dispatching to different nodes events that belongs to the same saga instance would mean easily incurring into nondeterministic behaviors.
These problems don't occur if events of the same saga instance are delivered, in order, to the same node.
So IMHO, in the case of sagas, the optimal event partitioning - namely that, in theory, should ensure a more uniform load balancing - is at instance level.
In my opionion this is not always possible - due to the broker nature - or easy to implement - due to modeling constraints.
I try to explain: Given that the association between an event and his saga is managed by the AssociationValue, to allow event partitioning at saga instance level probably we need to impose the constraint that all the events of a saga must share the same AssociationValue.
This constraint was not imposed, wisely I believe, in Axon. Is thus possible to design a Saga that is closer to the business process that you want to manage.
In
the example provided with the documentation you can find a case like this:
OrderManagementSaga is free to use different
associationProperty for different kind of events without restrictions. If otherwise, all events should be associated with the property orderId with a significant development burden and a less clear domain model.
In this way you are still free to put this constraint, but only in cases in which you feel useful or necessary.
I am pretty confident that Allard will soon provide us an elegant solution to this case as well. ;-)
For this reasons, i use to implement event partitioning by consumer type for all consumers that require in order dispatch and sticky load balancing, whereas I leave it to the broker in all other cases. I resort to partitioning at the saga instance level only for extreme cases.
Cheers,
Domenico