Java – Event handler replay when restarting application?

Event handler replay when restarting application?… here is a solution to the problem.

Event handler replay when restarting application?

I play Axon servers locally. I run a docker container on my local machine via the command docker run -d –name axonserver -p 8024:8024 -p 8124:8124 axoniq/axonserver.

When I start the spring-boot application, the event handler outside the aggregate reruns all previous events, so I see this log statement flow at startup.

The same event handler also issues a command to the aggregate, which then appends the new event to the aggregate that processes the command. So every time I restart the app, my aggregate ends up adding some events at the end of it, and I only need or expect one.

flsh.axon.LetterSchedulingHandler   : Sending letter 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f...
flsh.axon.LetterSchedulingHandler   : Sending letter 6b4f6966-85ea-46e0-9c49-21bcd501a1b5...
flsh.axon.LetterSchedulingHandler   : Sending letter fc36292f-c7bd-4575-b56f-130624a87466...

flsh.axon.Letter                    : LetterScheduledEvent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SCHEDULED
flsh.axon.Letter                    : LetterScheduledEvent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SCHEDULED
flsh.axon.Letter                    : LetterScheduledEvent fc36292f-c7bd-4575-b56f-130624a87466 SCHEDULED
flsh.axon.Letter                    : Letter sent fc36292f-c7bd-4575-b56f-130624a87466 SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent fc36292f-c7bd-4575-b56f-130624a87466 SENT
flsh.axon.Letter                    : Letter sent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SENT

My event handler looks like this:

@Slf4j
@Component
public class LetterSchedulingHandler {

private final CommandGateway commandGateway;

public LetterSchedulingHandler(CommandGateway commandGateway) {
        this.commandGateway = commandGateway;
    }

@DisallowReplay //this doesn't seem to work
    @EventHandler
    public void handle(BeginSendLetterEvent event) {
        log.info("Sending letter {}...", event.getLetterId());
        commandGateway.send(new LetterSentCommand(event.getLetterId()));
    }
}
@CommandHandler
public void handle(LetterSentCommand cmd) {
    AggregateLifecycle.apply(new LetterSentEvent(cmd.getLetterId()));
}

These events are published through the dispatcher… Run in the aggregate with different @CommandHandler, otherwise it will run successfully as expected.

@CommandHandler
public Letter(ScheduleLetterCommand cmd, EventScheduler scheduler) {
    String id = cmd.getLetterId();
    log.info("Received schedule command for letter id {}", id);
    ScheduleToken scheduleToken = scheduler.schedule(Duration.ofSeconds(5), new BeginSendLetterEvent(id));
    AggregateLifecycle.apply(new LetterScheduledEvent(id, scheduleToken));
}

@DisallowReplay comments don’t seem to prevent this. Also, I try to pay attention directions Here makes the handler a Subscribing event handler, but either I didn’t get it right or it didn’t solve the problem either.

axon:
  axonserver:
    servers: localhost
  eventhandling:
    processors:
      LetterSchedulingHandler:
        mode: subscribing

Solution

The @GoldFLsh you are missing is one of the following:

  1. Correctly reference the EventProcessor behind LetterSchedulingHandler
  2. Defines the @ProcessingGroup of the LetterSchedulingHandler

You may be in the What you read in the reference guide on Event Processors, because any event-handling component, such as reading your letterSchedulingHandler, will be grouped with other event-handling components in the subscription or tracking event handler.

However, you have not configured any processing group names at this stage. This means that the processing group for the LetterSchedulingHandler will default to the handler’s package name. Therefore, in your properties file, you should define it as a subscription using the package name instead of LetterSchedulingHandler.

But to be clearer, add a @ProcessingGroup comment on the LetterSchedulingHandler to give it a clear name, and then you can use it in your properties file.

Finally, the fact that you are not referencing the event handler correctly is why you see event replays. Axon defaults to the TrackingEventProcessor, which tracks the progress of processing stream events. If there is no persistence unit to store these TrackingTokens, it will always start from scratch.

Related Problems and Solutions