Can Sagas be started from Commands instead of Events

Hi

I am doing a poc on axon. Is there any conceptual reason why Sagas should not be started directly by command messages and implement command handlers? In the axon framework I see explisit support for having Sagas started by events and the documentation for Saga states that Sagas are instances that handles events.

I would like to use Sagas for managing long running commands accros multiple aggregate roots. Also sometimes I would like to have multiple active Sagas communicating with each other directly through command messages instead of indirectly via events (similar to Akka actors).

I understand that I as an alternative can implement message handlers that validates the message and then publishes an event that eventually will triggers the creation or reaction of the Saga, but why is this way better?

I have looked at the Saga definition for NServiceBus http://docs.particular.net/nservicebus/sagas-in-nservicebus an it seem less focused on starting Sagas from events, it talks about messages. Am I missing something with respect to the underlying design of the axonframework, or is it a perfectly good idea to implement command and event handlers in Sagas? Is it problematic to have both?

Thanks
Henrik

Hi Henrik,

this is a topic that I’ve been thinking about for a while. Having Sagas react to commands can be helpful in certain scenarios. The urgency of the feature simply hasn’t been high enough to make it to the top end of the roadmap. Whether there are practical issues in the current design of Axon, I don’t know. But I don’t think so.

I have created AXON-270 to track the issue. If you have any ideas about an API or implementation, don’t hesitate to let me know.
Cheers,

Allard

Hi

Good to know that this scenario is not excluded by design. Thank your for your answer and for creating an issue for my question. I will let you know if I end up implementing this.

What I am looking into is how this will work in a distribuded environment where saga1 and saga2 are two instances each living in a different cluster member. Most likely the two sagas will be of different types. If saga1 publishes a command that is targeted (handled) by saga2 then the framework should be able to figure out where to send the command since it will know in witch cluster member Saga2 lives (e.g from the hashcode of the saga id or the saga type). For events the framework must do something similar for each subscriber. I have not yet looked into how the distributed bus works but I assume this is more or less covered there. So I guess from a distribution point of view the problem og getting the commands and events to the right cluster member is the same. Is that a correct assumption?

The way I see it, this then boils down to how I design the message flow between saga1 and saga2.

Alternative 1: Saga1 can publish an event saying “I have done X” and hope saga2 will listen for event X and when it occurs then say “I have have done Y”. Furthermore saga1 can then listen for event Y and then say “I have done Z”.

Alternative 2: Saga1 can publish an event saying “I have done X” and in the same unit of work (transaction) send a command to saga1 saying (doY). Similarly saga2 will publish “I have done Y” and send command “doZ” to saga1. For this alternative it is of cause optional whether or not saga1 and saga2 publishes any events, but having the events there will make it simpler to add addtional (perhaps external) reactions to the main message flow. In this alternative I will also have to define command messages doY and doZ, which may or may not be needed for other purposes thus adding more code.

I guess it is a matter of taste, design philosophy and requirements that decides what works best in each case, the difference being that Alternative 2 has a more explisit main flow of messages. Since aggregate roots only send out events and no commands, it makes sense to start out designing the message flow for sagas according to alternative 1 as this approach then covers all cases and is already supported for the framework. Have I understood the overall design principle for alternative 1 correctly?

Thanks
Henrik

kl. 11:35:57 UTC+2 fredag 3. oktober 2014 skrev Allard Buijze følgende:

Hi Henrik,

distribution of the saga (managers) is a difficult subject. When it comes to commands, routing is done based on the ID of the command’s target entity. It could be a Saga ID, or an Aggregate ID, that doesn’t matter. The problem lays in the fact that sagas can be “associated” with different concepts and they need to process events as if they are received sequentially.

I don’t see an issue with multiple sagas cooperating. If one saga publishes an event (and the unitOfWork / transaction is committed), it will eventually arrive at the other saga. Just make sure you don’t expect a “reply” in the same method. If you use a command, then you can wait for a reply in the same method.

Cheers,

Allard

Yes, what you write is also the way I percieve it after having read the documentation on the axonframework.

In the scenario I am looking at I do not forsee that the sagas will be working on same aggregates at the same time. Saga1 will hand off part of the job to saga2 and saga1 will be “sleeping” (waiting for a command/event from saga2) until saga2 is done. Saga2 will be a kind of coordinator (probably a singleton) that accepts commands from multiple sagas and when certain conditions are met it will send a “go ahead/contition met” command/event to saga1.

I think what I am also trying to come to terms with is when to model a message as a command and when to model is an an event. I hope it will become apparent what to use when I start modelling the scenario in more detail. I guess I have a little bit of a problem with modelling obvious reply messages as events that must have at least one specific reciever (i.e it is a configuration failure its not listening).

Regards
Henrik

kl. 09:28:40 UTC+2 mandag 6. oktober 2014 skrev Allard Buijze følgende: