Using Tracking Event Processor for Sagas without event sourcing

Hi there

I recently switched from tracking event processors back to subscribing event processors. When implementing this switch I also moved from event sourcing to the state-based approach using JPA to save the state of the aggregates.

My question:
Is it possible to configure axon to use tracking event processors for sagas combined with a state-based approach (meaning without event-sourcing)?

If the answer is yes:
How is it configured?

I use axon release 3.3.3 and spring boot.

Thanks for any help.

Cheers
Marco

Hi Marco,

whether an Aggregate is Event Sourced or stored as state, is dictated by the repository used. By default, the Axon Spring Boot Starter will configure an Event Sourcing Repository for you, if you have an Event Store configured and if your aggregate is not annotated with JPA’s @Entity.
So in your case, you could define an event store, and simply configure your aggregate to be state stored, either by using @Entity and Spring Boot Autoconfiguration, or by specifying a repository for that aggregate explicitly, that uses stored state to reconstruct the aggregate.

So you could an event store to “synchronize” the events, but you can also consider using another type of message broker in that case.

Hope this helps.
Cheers,

Hi Allard

Thanks for this very quick response!!!

Just to check whether I understood you correctly:

  • Yes it is possible to setup tracking event processors only for sagas

  • I do have to define an event store for this purpose. Correct?
    My question?

  • As all my aggregates are state-based (i.e. annotated with @Entity) no events will ever be stored in the event store. Correct?

  • How will my sagas (which use a tracking event processor) be notified about events if there is only an empty event store (nothing can be tracked, where does the tracking-token point-to)?
    The only feature I need of the tracking event processor is the async behaviour which stands in contrast to the subscribing event processor which is sync (i.e. same thread).

Cheers
Marco

Hi Allard

I further read into the topic. As I don’t need a persisted event store I can just leave the SimpleEventBus as is and use this one. Correct?

Regarding the processing of the events I have two possibilities:

Possibility 1: Use a subscribing event processor but make use of the AsynchronousEventProcessingStrategy in order to implement the async behaviour.

@Bean
public SagaConfiguration<RecurringTaskSchedulingSaga> configBean() {
    SagaConfiguration.subscribingSagaManager(RecurringTaskSchedulingSaga.class, ....);
}

Possibility 2: Use a tracking event processor. Because we do not define a token an in-memory token is used which is okay for my purpose.

@Bean
public SagaConfiguration<RecurringTaskSchedulingSaga> configBean() {
    return SagaConfiguration.trackingSagaManager(RecurringTaskSchedulingSaga.class);
}

Questions:

  • Do both possibilities work out and which one would you prefer?
  • Is it needed to define such a configuration for each saga explicitly or is there possibility to tell axon that all sagas have to use possibility 1 or 2?
    Cheers

Marco

… followup

I tried to implement possibility 1 as follows (i am using spring boot…):

@Bean
public SagaConfiguration<RecurringTaskSchedulingSaga> sagaConfiguration() {
    return SagaConfiguration.subscribingSagaManager(RecurringTaskSchedulingSaga.class, Configuration::eventBus,
            c -> new AsynchronousEventProcessingStrategy(Executors.newCachedThreadPool(), new SequentialPerAggregatePolicy()));
}

caused the following exception: java.lang.IllegalArgumentException: Event processor with name RecurringTaskSchedulingSagaProcessor already exists

Then I tried to configure it as follows…

@Bean
public Configurer config() {
    Configurer configurer = DefaultConfigurer.defaultConfiguration();
    configurer.registerModule(SagaConfiguration.subscribingSagaManager(RecurringTaskSchedulingSaga.class, org.axonframework.config.Configuration::eventBus,
                    c -> new AsynchronousEventProcessingStrategy(Executors.newCachedThreadPool(), new SequentialPerAggregatePolicy())));
    return configurer;
}

… this seems to work but I find it rather odd to it like that…?!?

Is there a more sound way to do it.

Cheers
Marco

When implementing one of the possbilities with spring boot defining such a bean in the spring configuration the

… followup from followup :slight_smile:

I found it out or read the manual (https://docs.axoniq.io/reference-guide/v/3.3/part-iii-infrastructure-components/spring-boot-autoconfiguration)

Hi Marco,

Just quickly jumping in here, but if you want to use Tracking Event Processor (TEP) you are required to have a StreamableMessageSource implementation to provide the events to your TEPs.
There are currently two implementations of these available when using Axon:

  1. The EventStore
  2. The Kafka Extension

A StreamableMessageSource is needed as the TEP allows you to read from any given point in the event stream.
If you haven’t stored the event stream anywhere, you’d simply be incapable of using the TEP.

Shortly put, I think it simplest to keep the event store around.
Then again, I don’t know your exact use case and why you/your team have deduced events aren’t necessary anymore.

Hope this clarifies things!

Cheers,
Steven