Send commands from events

379 views
Skip to first unread message

Sara Pellegrini

unread,
Oct 27, 2017, 2:02:28 PM10/27/17
to Axon Framework Users
In an enterprise environment it is common to have different applications (Bounded Context) that feed a single Event Store.

When an event generated by "Bounded Context 1" must cause a command to be sent to "Bounded Context 2", a possible solution might be to use an EventHandler.
However, this solution causes problems in case of a replay, because sending the commands must be executed only once.
Is it a good idea to send commands via an EventHandler and, if so, how to behave in case of replay?

Wouldn't it be better to use another component (which can be assimilated to a Saga) capable to handle events from another Bounded Context once and once only?

How did you solve such cases?

Many thanks

Allard Buijze

unread,
Oct 30, 2017, 5:05:17 AM10/30/17
to axonfr...@googlegroups.com
Hi Sara,

I don't think there is anything wrong per-se with sending commands from an Event Handler. Obviously, replaying such a component would be wrong, as you would generate all the side-effects, again. 
In Axon, replays are always performed by for a certain component. It's not the entire system that's being replayed. In Axon 3, you would reset a TrackingProcessor to force a replay. If you simply never reset the tracking processor that contains these command-sending-event-handlers, you're fine. You should organize your event handlers so that the ones that can be replayed are separated from the ones that can't.

Hope this helps.
Cheers,

Allard

Op vr 27 okt. 2017 om 20:02 schreef Sara Pellegrini <sara.pe...@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Sara Pellegrini

unread,
Nov 9, 2017, 2:01:48 PM11/9/17
to Axon Framework Users
Hi Allard,
Thank you for your answer.

Initially I needed to send commands only in certain specific situations. 
Therefore I populated a projection on the basis of which decide whether or not to send a command.
So I created two EventHandlers, the first one to populate the projection and the second one to send commands at some events arrival, depending on the projection data.
In order to take decisions based on an updated projection, I put the two EventHandlers into the same ProcessingGroup, to be sure that events will be processed sequentially.

Currently I need to rebuild the projection based on different business logics. 
But I don't want to send again commands derived from events already processed.

Therefore the two EventHandler shouldn't be in the same ProcessingGroup, to be able to replay only one of them.
But, as said above, if I use different ProcessingGroup, I cannot be sure that the events will be processed sequentially.

Indeed this case made me wonder if there's some better way to solve my issue.
There's a way to create a dependency between to distinct ProcessingGroups?

Thank you again

Allard Buijze

unread,
Nov 9, 2017, 2:21:14 PM11/9/17
to axonfr...@googlegroups.com
Hi Sara,

interesting problem. To be honest, I don't have a solution ready for you.
One thing that spring to mind, is that you could keep track of the token that you last processed in the command-sending component, and replay up to that token without sending commands. From there, you can send commands again.

I doubt "connecting" two processors would be a solution, as it would require coordination between two otherwise independent threads. Also, I have no idea how this could be done with the parallel processing that Axon 3.1 could do.
I will give it some thought. It's an interesting idea to be able to block some event handlers from generating side-effects until the processor has reached a new stage.

All ideas are welcome ;-)
Cheers,

Allard

Op do 9 nov. 2017 om 20:01 schreef Sara Pellegrini <sara.pe...@gmail.com>:

Steven van Beelen

unread,
Nov 10, 2017, 5:18:42 AM11/10/17
to axonfr...@googlegroups.com
Hi all,

So we've got somewhat of a similar approach of two different Event Handling Components requiring each others state to be up to date.
In our case it's not to publish a command, but to not duplicate query model logic; thus we've got one query model relying on another query model.
We've thus got a dependency on one query model being up to date prior to the other Event Handling Component querying that model.
We're currently solving this dependency by putting the Event Handling classes for both query models in the same Event Processor group with the @ProcessingGroup annotation, and adding the @Order (read: Spring annotation) annotation to guarantee that the first Event Handling component is called prior to the latter.

Within the group we eventually also added Event Handling components which publish messages on a queue based on certain query models.
We thus have a side effect (like Allard is referring too) which we do not want to happen again if we replay that specific event processing group.
For now we've introduce a application property denoting whether the application is in replay or not, which is a stop gap we add to any side effects in our Event Handling Components which are backed by a Tracking Event Processor.
More ideal would be to put the message publishing event handling component in it's own Tracking Event Processor group and to give it some means to check whether the Event Processor it's relying on for the query model is up to date.
Up to date in this sense means that the Tracking Token of the message publishing component is smaller or equal to the Tracking Token of the query model updating component it's depending on.

I believe however that the Tracking Token checking between two distinct processing groups I'm suggesting here is something we cannot do at this point in time.
Let alone how we do that with parallel Tracking Event Processors...

Sara, does my explanation here resemble what your situation is?
At least I agree it to be beneficial if we introduce a solution to have some form of dependency between Tracking Event Proccessors; it's not that odd a situation to have.

Hope this gives some insights, happy to discuss this further as well!

Cheers,

Steven  


Sara Pellegrini

unread,
Nov 13, 2017, 6:28:09 AM11/13/17
to Axon Framework Users
Hi Steven,

Momentarily, I've use an application property too, but this forces me to perform a manual action at the end of the replay.
To have TokenEntry "smaller or equal" is not enought for my case, because after the index has reached the target, the two handlers should be proceed togheter.

Maybe a possible solution could be to have a way to send a kind of notification from EventHandler to a Saga, responsible to send commands.
During replay, the notifications has no effects because the Saga doen't exists anymore, so no command is replayed.
To explain better my idea: 

Sara Pellegrini

unread,
Nov 13, 2017, 6:41:47 AM11/13/17
to Axon Framework Users
Maybe this is more clear:

Allard Buijze

unread,
Nov 13, 2017, 8:19:13 AM11/13/17
to axonfr...@googlegroups.com
Hi Sara, Steven,

I have had plenty of airport waiting time last week, and gave this some thought. At first (when discussing this with Steven) I was looking in the direction of somehow connecting two processors. However, I think the solution is much simpler than that.

At the moment, triggering a replay is a "manual" job. You need to remove the token and clear the projections. We have been talking about adding an explicit API to the TrackingEventProcessor to make this easier. Just like "start" and "shutdown", there should also be a "reset" method.

The initial idea was to either allow handlers to reset, or prevent resetting the processor, which would, for example, be the case with Sagas or any event handler that causes a side-effect (email, external systems, etc). Any solution in that direction quickly resulted in a type of complexity that made it almost unbearable.

The approach that we're currently looking into is to support "partial reset". When resetting a Processor, it would invoke all "pre-reset" handlers and check if all handlers support this reset. If one or more handlers don't support reset, a special token is used. If all handlers do support a reset, the token is cleared as part of the reset. If no handlers support resetting, the reset should be rejected.

This special token, a PartialResetToken would contain the original token as well as the token that is being processes at the moment. So if at a moment when the token is Tx, the processor is reset, a PartialResetToken (Tx, null) would be created. The null represents the lack of a token for the "general handler population", causing it to track from the beginning of the stream. This token is then updated until it is equal to Tx (or when one token "covers" the other). In that case, the reset is considered complete and the processor is continuing work where it left off. From that moment on, the handlers that didn't support reset are also invoked.

While this process might seem complicated, the main advantage is that it doesn't affect any other components than the processor itself. The processor will need to be able to detect whether it is using a PartialResetToken and extract the two subtokens from it. That's easy. Somewhat harder, but also already solved as part of another story in Axon 3.1 is being able to tell the relative difference between two given tokens,allowing the TrackingProcessor to recognize when it has finished a replay.

Hope this makes some sense.
Cheers,

Allard

Op ma 13 nov. 2017 om 12:41 schreef Sara Pellegrini <sara.pe...@gmail.com>:

Sara Pellegrini

unread,
Nov 21, 2017, 4:37:11 AM11/21/17
to Axon Framework Users
Hi Allard,

your proposal fully resolves my issue.
In this way, also the classic username uniqueness issue can be solved directy from the event handler.
Reply all
Reply to author
Forward
0 new messages