Yes not a new thing
We should be more precise in our language and distinguish the two concepts even though they tend to have similar implementations intent can be different
Code to the message is especially cool with document messages
Sarunas,Activities and sagas are quite different in my opinion. They are both extremely useful in building distributed systems in a simple way, but serve different purposes.However, there is a collision between current CQRS development practices and Helland's ideas. It comes from the fact that it is allowed and encouraged to have state (essentially conversation memory) inside sagas. This makes sagas look like Activities that were somehow pushed out of BCs. The latter does not make a lot of sense, since activities must be within the consistency boundary (in Helland's terminology, they have to be within the transactional scope with the entities they help to manage).However, if we (wildly) assume that sagas should not have any state and be "dumbed" down to simple messaging conversion and routing, then everything becomes more straightforward. Essentially we push conversation memory (and related actions) back to the Activities inside the BCs (even though there might be no actual "activity" class in there).There are advantages of this approach:
- Since conversation memory is inside an AR now, it's much easier to develop and test everything (well, as long as CQRS+ES is used)
- No need to worry about load-balancing and partitioning saga persistence (or synchronizing state), since sagas are stateless and inherently idempotent.
- Testing sagas becomes much easier (not sure if you even need to test that).
The biggest drawback - that workflow starts feeling a bit fragmented if we talk about actual "normalized" messages passing around (where message contains absolute minimum of information). If, however, we step back from purist development approach and closer to the real world (where there are various redundant documents passing between organizational entities) and allow a little bit more duplication, then suddenly everything becomes simpler.This works fine for me, since I already allow quite a bit of data duplication in terms of event sourcing and expendable read models.BTW, the second drawback of this approach is that implementing Helland's activities in relational world can be quite expensive (due to inherent friction and object-relational impedance mismatch). +ES is totally different story.However, I understand, that this is just one of many approaches. And my further experience might prove me horribly wrong for "breaking" proper sagas and taking state away from them (or doing a few other really bad things). So far it works though, starting from the code (efficiency of coding) up to architecture (ease of evolving the system according to real world models) and up to maintenance (ease of running systems for years in various deployment scenarios, starting from on-premises and up to hybrid clouds).Does this help?Best wishes,RinatOn Thu, Oct 6, 2011 at 8:00 PM, Sarunas Mazylis <apkr...@gmail.com> wrote:
I had a feeling that sagas are more like what Helland calls activities and live inside a BC serving as conversation memory with other BCs. No?
On Thu, Oct 6, 2011 at 4:27 PM, Rinat Abdullin <rinat.a...@gmail.com> wrote:PS: and these saga implementations, obviously, live outside of any bounded context at the logical level.On Thu, Oct 6, 2011 at 7:25 PM, Rinat Abdullin <rinat.a...@gmail.com> wrote:
Damian,Not sure, if you your post refers to my code snippets. If it does not, then my apologies for misunderstanding. If it does refer, then:What Udi called "event handlers" in snippets, are just technical implementation of sagas in my system. At the architectural level these handlers are still combined into a saga. At the code level these handlers are a member of a single saga class as well. These classes:* help to structure bounded contexts and orchestrate workflows* bring in time and timeout events in order to run long lived transactions* help bounded contexts to stay decoupled and unaware of each other* simplify message routing in load-balanced distributed scenariosI believe, that's what sagas do "by the book". Please, correct me if I'm being wrong here.I understand, that the code of my sagas might look like different, when compared to accepted coding practices in NSB/MT/RQ etc. But that's just the implementation being consciously chosen for a number of benefits.What do you think?Best regards,RinatOn Thu, Oct 6, 2011 at 7:07 PM, Damian Hickey <dhi...@gmail.com> wrote:
There is something about an event handler in a one BC that knows of commands from another BC that doesn't sit will with me. It would seem that the boundaries are leaky and have undesirable coupling?
If it's just a case that "one man's event is another man's command", then instead of your event handler in your first BC issuing a command, the event handler actually lives in the second BC where the event published by the first BC is converted to a command. The risk with this approach is that you may inadvertently end up creating 'conversations' between the two BCs where the conversation 'state' is somehow stored in both BCs, so watch out for that.
If you require distributed consensus, i.e. say the command fails in the second BC and you need to issue a compensating command to the first BC, then it looks like a Saga is the way to go.
My 2 cents... I reserve the right to be wrong :)
Rinat, are you only using commands that do not fail? If not who deals with failures, retries, etc.?
I see, this is very nice and is feasible with external services too. Thanks for the detailed reply.
Smalltalk-80: The Language and its Implementation
http://wiki.squeak.org/squeak/64