Add Temporal Nexus Operation Handler#2842
Conversation
a33ff01 to
7e61dab
Compare
| throw new HandlerException( | ||
| HandlerException.ErrorType.INTERNAL, | ||
| new IllegalStateException("TemporalOperationResult must be either sync or async")); | ||
| } |
There was a problem hiding this comment.
Unreachable else branch is dead code
Low Severity
The else branch in TemporalOperationHandler.start() is unreachable dead code. TemporalOperationResult.isSync() returns the isSync field, and isAsync() returns !isSync — they are always complementary. No instance of TemporalOperationResult can ever be neither sync nor async, so the HandlerException at the bottom can never be thrown.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7e61dab. Configure here.
| private final WorkflowClient client; | ||
| private final OperationContext operationContext; | ||
| private final OperationStartDetails operationStartDetails; | ||
| private boolean asyncOperationStarted; |
There was a problem hiding this comment.
Forgive my lack of Java concurrency know how, but could this flag cause a race if you call startWorkflow concurrently? Both attempt to start, race past the check and successfully start a workflow.
7e61dab to
f2c65fc
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default mode and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Reviewed by Cursor Bugbot for commit f2c65fc. Configure here.
| // Set after successful start so that if startWorkflowAndAttachLinks throws, | ||
| // the handler can retry without being blocked by the guard. | ||
| asyncOperationStarted = true; | ||
| return TemporalOperationResult.async(response.getOperationToken()); |
There was a problem hiding this comment.
Non-thread-safe check-then-act on asyncOperationStarted flag
Medium Severity
The asyncOperationStarted boolean field uses a check-then-act pattern without synchronization. If startWorkflow is called concurrently from multiple threads sharing this client instance, both calls can race past the if (asyncOperationStarted) check before either sets the flag to true, resulting in two workflows being started when the invariant requires at most one. Making the field volatile alone wouldn't fix the TOCTOU issue; an AtomicBoolean with compareAndSet or synchronized block is needed to make the guard atomic.
Reviewed by Cursor Bugbot for commit f2c65fc. Configure here.


Add TemporalOperationHandler for generic Nexus operations
Goal
Provide a new base to make it easy to expose more Temporal actions as Nexus Operations
Summary
Test plan
Note
Medium Risk
Adds new public Nexus handler/client APIs and changes operation-token parsing/cancel dispatch behavior, which could affect async operation lifecycle and cancellation semantics. Risk is moderate since changes are mostly additive but touch workflow start/link attachment and token validation used across Nexus operations.
Overview
Adds a new generic
TemporalOperationHandlerAPI that lets Nexus operation implementations return either sync results or start an async workflow via a newTemporalNexusClient(typed overloads + untyped) andTemporalOperationResult.Refactors workflow-start/link attachment into
NexusStartWorkflowHelperand updatesWorkflowRunOperationImplto use it.Renames and generalizes workflow-run tokens to
OperationToken, extendsOperationTokenUtilwithloadOperationToken(type-agnostic) while keeping a workflow-run asserting loader, and adds/updates tests covering typed/untyped starts, sync results, double-start guard, and cancel dispatch.Reviewed by Cursor Bugbot for commit f2c65fc. Bugbot is set up for automated code reviews on this repo. Configure here.