microsoft / durabletask-java

Java SDK for Durable Functions and the Durable Task Framework
MIT License
13 stars 7 forks source link

Eternal Orchestrator is replaying external event infinitely #182

Closed kanupriya15025 closed 7 months ago

kanupriya15025 commented 7 months ago

Following up on https://github.com/microsoft/durabletask-java/issues/136

@kamperiadis Now the event is read properly but in a code similar to this :

    Task<Something> event = ctx.waitForExternalEvent("Approval", Something.class);
    Task<?> timer = ctx.createTimer(Duration.ofDays(7)); 
    Task<?> winner = ctx.anyOf(event, timer).await(); 
    if (winner == event) {
        response = event.await();
        if (!ctx.getIsReplaying()) {
            context.getLogger().info("winner is the external event");
            ctx.continueAsNew(response);
            return;
        }
    }
    else {
        context.getLogger().info("winner is the timer");
    }

The log line "winner is the external event" keeps on printing infinitely. (Note that it's under a condition, so the log line is not replaying. The event is somehow being replayed again and again with each execution.

kaibocai commented 7 months ago

Hi @kanupriya15025, this is not an issue caused by the long timer. Instead, it's an issue when sdk decides which events to carry over for continueAsNew.

The fix is ready to merge https://github.com/microsoft/durabletask-java/pull/183

For now, you can use this as workaround if your code doesn't need to carry over unprocessed events to the next orchestration invocation after calling continueAsNew.

    Task<Something> event = ctx.waitForExternalEvent("Approval", Something.class);
    Task<?> timer = ctx.createTimer(Duration.ofDays(7)); 
    Task<?> winner = ctx.anyOf(event, timer).await(); 
    if (winner == event) {
        response = event.await();
        if (!ctx.getIsReplaying()) {
            context.getLogger().info("winner is the external event");
            ctx.continueAsNew(response, false);
            return;
        }
    }
    else {
        context.getLogger().info("winner is the timer");
    }