More asynchronous processing with Axon in version 4 ?

Hi everybody.

When I try to migrate my application (Spring boot with event sourcing) from Axon version 3 to version 4, I have some problems with asynchronous processing. Under Axon 3, I didn’t have such problems.

What exactly has changed with version 4 in this area? Among other things, I have read that in version 4, events are processed in a separate thread by default. Is this synonymous with “asynchronous”?

Is there a way to completely rely on synchronous processing?

My current Axon configuration can be seen here: https://github.com/oregami/oregami-game-database-cqrs-2019/blob/axon-4/src/main/java/org/oregami/config/AxonConfiguration.java

Thanks in advance,
Sebastian

Indeed Sebastian,

Axon has two types of event handlers: Tracking (asynchronous, different thread) and subscribing (synchronous, same thread). While subscribing event handlers was the default in Axon 3, since Axon 4, Tracking event handlers are now the default (also for Sagas).

If you want your eventhandlers to be subscribing again (same behaviour as Axon 3), you will need to configure them that way.

See the following documentation: https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/event-processing/event-processors

To make all event listeners subscribing, you would need to add:

// Default all processors to subscribing mode.
@Autowired
public void configure(EventProcessingConfigurer config) {
config.usingSubscribingEventProcessors();
}

Tracking eventhandlers make use of a Tracking token, to track which events were already processed by a listener.

The reason why this changed is probably a design decision, which makes Axon closer to the DDD (Domain Driven Design) principles. Following DDD, everything that happens within an Aggregate boundary, is ACID, transactional, absolutely consistent. However, everything that happens outside an Aggregate (like event handling), is eventual consistent.

Stijn (just an Axon user)

Hey Stijn.

Thank you very much for your helpful reply!I am going to think about switching to synchronous processing then with the configuration you mentioned.

Does the decision between tracking and subscribing event processors affect the possibilities to replay events later to rebuild the read model? I think I have read anywhere that you need a “TrackingEventProcessor” to do this…

Thanks,
Sebastian

Correct again Sebastian,

You can only do replays with Tracking eventhandlers. When you ask Axon to do a replay, Axon will reset the token, and the event listeners will reprocess the events. Every tracking event handler can be replayed separately.

It is better to design your system in a way that it can deal with eventual consistency and tracking event handlers. When dealing with subscribing event handlers, your system can block thread and be must less responsive. With tracking eventhandlers, you can build a much more performant system. True, you will have to deal with asynchronous handling of the listeners, which is more complex.

Hey,

thanks again for your reply.
Phew, I’ll have to think about which way to go.

I have a use case in my application where the user creates a new aggregate instance and in the same action this new instance (better say: it’s ID) should be added to another aggregate instance (of another type). My adapter class calls two application service methods for this, and with asynchronous exection of the first one the second one does not work…
As I wrote above, I’ll have to think about it :slight_smile: