Synchronous cluster with a sequential policy

Hi,

About event processing, according to the documentation : “By default, event listeners process events in the thread that dispatches them”.
So i thought that when you use synchronous cluster, all the listener are called sequentially and in the same order. But i have noticed, that it’s not true, especially i don’t understand why listeners are not called sequentially : in other words, the methods in the listener don’t expect the end of the previous method to start (in fact, if i understand, the synchonous cluster can use other threads to call listener methods, and not only the current thread as i thought).

I like Asynchronous listener especially with SequentialPerAggregatePolicy : is it possible to have the same behavior with a synchronous listener ? My purpose is that the thread that executes the command will have to wait until all event handling has finished (so, the user can validate a form in the user interface, and can view the result with good data, not obsolete).

Best regards.

Baptiste.

Hmm, I made a mistake, i have used “CommandGateway.send” in my listeners, instead of “CommandGateway.sendAndWait”. So it explains why i have multiple threads during the command processing.

So, my initial question becomes : is it possible to define an order between the listeners when we use a synchronous cluster (using @Order annotation like asynchronous cluster) ?

Cheers,

Baptiste.

Hi Baptiste,

yes you can. See http://www.axonframework.org/apidocs/2.3/org/axonframework/eventhandling/SimpleCluster.html#SimpleCluster(java.lang.String,%20org.axonframework.eventhandling.OrderResolver). When using Spring, you can put Spring’s Ordered annotations on the listeners to define their order. Otherwise, provide an OrderResolver instance that defines the order.

Cheers,

Allard

Ok, it’s perfect :slight_smile:
I already use SpringAnnotationOrderResolver for my asynchronous cluster, but i thought that did not work with the simple cluster (maybe on a too earlier version ?).
Thanks.

Hi Allard,

However, i’m facing with a new problem : i call sendAndWait in the gateway to interact with an other aggregate, then an event listener call an other sendAndWait to interact to a third aggregate. I have noticed that when you call the second sendAndWait method, it waits indefinitly (it is the same lock for the gateway ?)

How can i preserve my sequential policy in my synchronous cluster without dead lock ?

Cheers,

Baptiste.

Hi,

I notice two terms being used interchangeably, while they mean different things. Just to be sure: the OrderResolver defines in which order Handlers are being invoked in a single cluster. The SequencingPolicy defines which Events must be handles sequentially, and which may be handled concurrently. The latter only exists in an Asynchronous cluster.

About the deadlock. It is probably cause by using sendAndWait, while as a result of the command (somewhere indirectly), another thread is waiting for a lock of that same aggregate. This can easily occur when command processing is done asynchronously, but events are handled in the thread that also handles the command. Handling events asynchronously as well will resolve the problem, as the lock can be released without having to wait for the events to be handled.

Using send and wait should really only be used in places where you must wait for the response in order to continue. Most commands shouldn’t provide a response, meaning there is no added value in waiting.

Cheers,

Allard

I’m particularly interested in this phrase.

Each user action (except for queries obviously) produce the execution of at least a command, so if the command fails for any reason (business logic or runtime error) the user needs to know it.
If SendAndWait is used, the failure can be reported to the user.
Otherwise it is necessary to build an asynchronous mechanism to send feedback to the user. I understand this is possibile and in some cases even valuable / preferable, but I think this is not the most common scenario.

Why “Most commands shouldn’t provide a response”? Is not success/failure a response?
What I think is “Commands shouldn’t provide a response except success/failure”.
I’m very interested in your opinion.

Thanks.

Hi,

you’re absolutely right. I rest my case. A success/failure (i.e. void vs exception) is also a response. However, an Exception should be an exceptional case, you should “almost” be able to assume they don’t occur ;-).

Async responses aren’t as uncommon as you may think. Servlet 3 has perfect possibilities to send the response asynchronously. I would definitely recommend using it. In the command bus, you’d then use a callback to send the response to the client.

Cheers,

Allard

Hi,

In case of “fire and forget” command. How can i be sure that read side is updated before to send the response to the client ?
In my architecture, i have a gwt client with RPC. the server side call the commandgateway, and for the moment with a “sendAndWait” method. If i call “send”, even if i implement call back, when the call back is called, i’m not sure that read-side is updated (i’m only sure that aggregate is updated).

Thanks.

The best design of a system is simply not to rely on the read side to be updated. There have been a lot of discussions on this, both on this mailing list as the ddd/cqrs mailinglist. I would recommend reading up on this.

In short: instead on waiting for a query to be updates when sending the result, you can also send an expected version when doing a query. The query could then wait for that version to have been applied to the query before returning the results.

Cheers,

Allard

Hi Allard,

Interesting technique. In several screens, i have to inform the user that data are updated because it is a classic form. If the user does not view the good data, he may think that there was an error during save.
I just find a link you posted few years ago : http://blog.trifork.com/2011/02/25/getting-gwt-to-work-with-servlet-3-async-requests

Do you use this technique yet ? do you have any update of this code ?

Thanks.

Cheers,

Baptiste.

Hi Baptiste,

in such a case, try to make the client wait for the “primary action” only. That is basically the processing of the first command, but not any commands that result from the events generated by the first. That would also resolve any deadlock situations you may have. Another solution is to wait for an event handler to have processed a certain event (recognized using correlation ids). However, that would add extra complexity, locks, etc.

The GWT async code is probably still actual. It did the job at the time. However, GWT has moved on since the time I wrote the article, so perhaps there are now better ways to do it. The project where I implemented this has changed the implementation to use websockets instead. That means all communication from client to server is done via a single websocket connection, while still using the GWT mechanism. I haven’t used GWT in any other project recently.

Cheers,

Allard

Thanks for your help.