axonaxon-framework

New Saga starts with 0 global index when specific name is given


I am a bit confused how Axon behaves when creating new saga-s. In past I have created sagas and given their ProcessingGroups specific name via constants so I can reference them in tracking process configurations. All previously added Saga-s had their tracking token initialized based on last global index (head of the stream).

Just recently we created new saga and also gave its group specific name, but this Saga started to process events from the tail of the stream? We haven't configured any specific configuration for this processor. However when I delete the token and remove the @ProcessingGroup annotation from saga, it starts from head again as expected.

Now I have tested even with 0 tracking processor configurations (removed entire config), and I observe the same behaviour.

When Saga is annotated with ProcessingGroup, then it starts from start and replays everything. Not expected.

When Saga is annotated with ProcessingGroup and I exclicitly configure head token, it starts from head as expected.

When Saga is not annotated with ProcessingGroup, then it starts from the head as expected.

object EventProcessors {
   const val onboardingSaga = "onboardingSaga"
}

@Saga
@ProcessingGroup(EventProcessors.onboardingSaga)
class OnboardingSaga {

    @StartSaga
    @SagaEventHandler(associationProperty = "onboardingId")
    fun on(event: OnboardingStartedEvent) {
      ...
    }
}

The example is very trivial, but when starting new Saga like this without any other Axon specific configuration, then Saga starts to handle all my existing events. But without the ProcessingGroup, it works correctly.

Current app is using Axon 4.6.2 on Spring Boot.


Solution

  • To be honest with you, that is slightly curious, @Vaelyr. As of Axon Framework version 4.5.0, Axon Framework defaults Sagas without any customization to the head of the event stream. To be more exact, this pull request introduced that behavior.

    The following pointers are taken as customization for sagas:

    1. A processing group name differing from the default
    2. Any Event Processor builder configuration for the given processor name
    3. Any TrackingEventProcessorConfiguration present for the given processor name

    Hence, the fact you used the @ProcessingGroup annotation should've influenced the above, thus not leading to a head token. The only way around this may be if your @ProcessingGroup annotation specified the default name, which is {saga-class-name}Processor.

    Nonetheless, I do think I have good news for you. The Axon Framework team felt that adding the processing group as a decision maker whether to have a default saga configuration wasn't clear nor correct. As such, this pull request removes that behavior (as well as adds the behavior when using a PooledStreamingEventProcessor).

    The referred pull request is part of Axon Framework 4.7.6, which thus does require you to upgrade to a more recent version of the Framework.

    I know there are breaking changes, sadly enough, but this blog post explains how you can resolve this. You can even use Axon's OpenRewrite recipes to upgrade automatically (as described in this blog).

    Concluding, I hope this explains the problem you're facing, @Vaelyr!