feat: Use per-context replay status #403
Open
ayushiahjolia wants to merge 1 commit into
Open
Conversation
SilanHe
reviewed
May 25, 2026
18745f5 to
216aae2
Compare
216aae2 to
3b35b3e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Issue Link, if available
Fixes #383
Adds per-context replay tracking to the Java SDK. This is a prerequisite for the plugin hooks feature (#364) and OTel integration (#333).
Problem
Log suppression during replay used the global
ExecutionManager.isReplaying()flag. When multiple branches run concurrently (parallel/map), the global flag flips to EXECUTION as soon as any branch encounters new work - causing logs in other branches that are still replaying to leak through.The old per-context field (
BaseContextImpl.isReplaying) was a one-shot transition guard used only byBaseDurableOperation.execute(). It was never used for log suppression and answered a different question ("has this context ever seen a non-cached op?") rather than ("is the next operation already checkpointed?").Solution
Added proactive per-context replay tracking in
DurableContextImpl:replayModefield - initialized by checking if the next operation (viapeekNextOperationId()) exists in checkpoint storageupdateReplayStatus()- called afternextOperationId()in each operation method; peeks at the following operation and transitions out of replay if it doesn't existisReplayingContext()- exposes the per-context replay status to the logger and future plugin hooksThis matches the Python SDK's
_track_replay()pattern: after consuming the current operation's ID, peek at the next one - if it's not in storage, we're past the replay boundary.Checklist
Testing
Unit Tests
Have unit tests been written for these changes? Yes
Integration Tests
Have integration tests been written for these changes? N/A
Examples
Has a new example been added for the change? (if applicable) N/A