When using a rest api, commandGateway.send is not working async

In Axon 3, when using a POST rest api, commandGateway.send is not working async and the response is waiting until the command is executed. Wasted a day debugging this. Need help.

Dear Harsh,

Most likely, you’re using the default CommandBus implementation, which is the SimpleCommandBus. This implementation is fully synchronous, which explains the behaviour you’re experiencing.

The solution is to set up a different CommandBus like the AsynchronousCommandBus. You can find some more information here: https://docs.axonframework.org/part3/command-dispatching.html

Don’t hesitate to reach out if you have any more questions.

Kind regards,

Thanks Frans.

I used the async bus as -

@Bean
public CommandBus commandBus(
ApplicationContext parentContext) {
AsynchronousCommandBus asynchronousCommandBus = new AsynchronousCommandBus();
((ConfigurableWebApplicationContext) parentContext).addApplicationListener((
ContextClosedEvent event) -> asynchronousCommandBus.shutdown());
return asynchronousCommandBus;
}

The issue now is that after reaching the commandHandler, the events are not getting published. Can you help me out with this issue ?

Hi Harsh,

On your comment alone I’m not sure how to help you, so I’ve got some follow up questions to figure it out.

  1. Does not getting published in this sense mean the event ins’t stored in your EventStore, or that zero Event Handling Components are reached?

  2. Do you get any exceptions or warnings in your console log after the AggregateLifecycle.apply() is called in your Command handling function to publish an event?

  3. Are you configuring any other Axon beans yourself apposed to using the Spring Boot Axon starter dependency?

Hopefully this will help you eventually.

Cheers,

Steven

Hi Steven,

Thanks for the quick reply, going further I realised that features where we want to use both commandGateway.sendAndWait(to make a step synchronous) and send are not working. In case of sendAndWait in asycCommandBus, the event ins’t getting stored in your EventStore and neither it is published to the handlers.

Did you configure the async bus to use a transaction manager?
There should be some logging or exception (note that the gateway returns a future that holds results) that indicates what’s going on.

Hi Harsh/Allard,

I think Allard suggests adding a Handler Interceptor to your AsynchronousCommandBus, like so for example:

@Bean
public AsynchronousCommandBus asynchronousCommandBus(TransactionManager transactionManager) {
AsynchronousCommandBus asynchronousCommandBus = new AsynchronousCommandBus();
asynchronousCommandBus.registerHandlerInterceptor(new TransactionManagingInterceptor<>(transactionManager));
return asynchronousCommandBus;
}

Allard, correct me if I’m wrong on this of course.

And like he already points out, the CompleteFuture you’d get on a CommandGateway.send() should also give you pointers of what you’re missing.

Hope this helps.

Cheers,
Steven

Hi Steven/Allard,

Thanks for the help. Worked like a charm.

Hi Steven/Allard,

Just to know things better, lets say I poll 60 mails per minute for one mailbox, so the commands raised are very high in number becuase there are many mailboxes. So we found that the default executor for async command bus which is the cachedThreadpoolExecutor is processing that very slowly, What might be the reason and how can we overcome that ? Do we need a different executor ?

Hi Harsh,

So, if I follow correctly you’ve something like 60 ‘SendMailCommands’ per minute, right?
I’m guessing those commands are (command) handled by some form of Aggregate, which will then apply events based on that event.
Additionally, I’m guessing you’re running it in a Spring Boot app.

I’d say that shouldn’t be an issue, but that does depend on how you’re event handling components are set up.
If you’ve just created a bean class with @EventHandling functions on it, without specifying anything specific in your configuration, Axon will automatically put every Event Handling component in a SubscribingEventProcessor.
SubscribingEventProcessor are registered to the EventBus directly, meaning that if the EventBus receive an event from your aggregate for example, that same thread will be used to call any Subscribing Event Processor groups and all the Event Handling components in them.

I’m guessing that’s now causing a slow processing speed in your application.

What you can do is put your Event Handling Components in TrackingEventProcessors.
A TrackingEventProcessor does a tail on the Event stream in it’s own trhead, thus will not block the command handling thread from the AsynchronousCommandBus.
More explanation around Subscribing and Tracking Event Processors can be found here.

Hope this helps Harsh!

Cheers,

Steven

Thanks Steven ! The concept tailing by tracking event processor is really nice. Finally large number of threads are being processed easily !

Hi Steven,

Out of 8 tracking processors, 2 of them are working very slow. This is the warning in logs:
An event processor fell behind the tail end of the event store cache. This usually indicates a badly performing event processor.

How can I optimise the processor speed ?

Hi Harsh,

That depends on what the Event Handling components within your TrackingEventProcessor group are doing, so I’d say that’s to general a question for me to answer.
I’d probably take a look at which services you’re calling and why those are taking so long, and then check if you can offload those to other threads.

Also some general info around Subscribing and Tracking Event Processors, which should also be available in the reference guide if I’m not mistaking.

Putting your Event Handling components in an TrackingEventProcessor group isn’t the golden solution though, you should take care when to use them.
Mainly, because a TrackingEventProcessor also means you’ve introduced replaying capability for the Event Handling components, because a TrackingEventProcessor keeps track of where it is in handling events from the event stream.
That means if you introduce a new TrackingEventProcessor in your system which already contains events, that it will start at the beginning of the Event stream and handle every event in there.
Event Handling components which for example send emails, update queues or maybe even upload data to another server are examples which you wouldn’t want to be able to replay, or when newly introduced would want to execute from the beginning of time.
Such event handling components would be better placed in a SubscribingEventProcessor.

Hope this gives you some extra insights.

Cheers,

Steven