I have an Axon 2.6 implementation that uses SimpleCommandBus, SimpleEventBus and DefaultCommandGateway to send commands. I send a command in a Jersey resource and my problem is that even though I use the send method (as opposed to sendAndWait) the HTTP response is not returned until the resulting event is processed. Any ideas on things that could cause this behavior?
You’re using the SimpleEventBus and that is handling the events synchronously in the same thread they’re sent. Hence your observed behaviour that the call doesn’t return until the event is handled.
Look up asynchronous event listeners in http://www.axonframework.org/docs/2.4/event-processing.html for some suggestions how to change that if you don’t want that kind of behaviour.
If you want to go all out on async, you can also consider using an asynchronous command bus and async servlet support.
I wrongly thought that event handling was decoupled from command dispatching even for the simple cases so I did not look further into the event options. I will do so and update this thread if others are interested in the same thing.
After carefully reading the docs I have now tried to configure a ClusteringEventBus with an AsynchronousCluster. The relevant code looks like this:
ThreadPoolExecutor clusterExecutor = new ThreadPoolExecutor(2, 10, 60L, TimeUnit.MINUTES, new SynchronousQueue<>(true));
Cluster cluster = new AsynchronousCluster("myAxonCluster", clusterExecutor, new NoTransactionManager(), new FullConcurrencyPolicy());
EventBusTerminal eventBusTerminal = new EventBusTerminal() {
@Override
public void publish(EventMessage... events) {
cluster.publish(events);
}
@Override
public void onClusterCreated(Cluster cluster) {
// No-op
}
};
return new ClusteringEventBus(eventBusTerminal);
The code runs and when reading the debug logs it seems like the events are published ok but the handler never gets them. The handler is connected to the event bus exactly like for the SimpleEventBus case.
not 100% sure if it is part of the problem, but let’s eliminate this first before moving on:
configure the bus as follows:
ThreadPoolExecutor clusterExecutor = new ThreadPoolExecutor(2, 10, 60L, TimeUnit.MINUTES, new SynchronousQueue<>(true));
Cluster cluster = new AsynchronousCluster(“myAxonCluster”, clusterExecutor, new NoTransactionManager(), new FullConcurrencyPolicy());
return new ClusteringEventBus(new DefaultClusterSelector(cluster));
The clusterSelector ensures that all registered event handlers are assigned to the given cluster. There are other selectors that use can use as well (or even combine them), if needed.
That did the trick, I must have messed something up with the terminal, I didn’t know you could set it up like in your example. Now it works and I can augment with different cluster selectors etc as needed.
Truly awesome help, thank you for quick responses.