Skip to content

Conversation

@Quinn-With-Two-Ns
Copy link
Contributor

@Quinn-With-Two-Ns Quinn-With-Two-Ns commented Oct 23, 2025

Add new constructor for WorkflowStub to target correct execution. Before the PR WorkflowStub was very inconsistent in what workflow execution it targets, sometimes it would ignore the RunID, sometimes it wouldn't. This PR keeps the old inconsistent behaviour if a user uses the old constructor and adds a new constructor that always uses the execution the user specified. It also adds the ability to target by FirstExecutionRunID to target a workflow chain.


Note

Introduce WorkflowTargetOptions to target workflows by workflowId, runId, or firstExecutionRunId; update typed/untyped stub creation to use it, deprecate legacy constructors, and ensure signal/cancel/terminate/update honor exact targeting.

  • Client API:
    • Add WorkflowTargetOptions (target by workflowId, runId, firstExecutionRunId).
    • New overloads:
      • newWorkflowStub(Class, WorkflowTargetOptions).
      • newUntypedWorkflowStub(WorkflowTargetOptions) and newUntypedWorkflowStub(WorkflowTargetOptions, Optional<String>).
    • Deprecate legacy constructors using (workflowId, Optional<runId>) and (WorkflowExecution, Optional<workflowType>).
  • Targeting semantics:
    • WorkflowStubImpl now respects explicit runId by default; preserves legacy behavior via legacyTargeting for deprecated paths.
    • Propagate firstExecutionRunId to updates, cancel, and terminate; add helpers to choose current vs chain (currentExecutionCheckLegacy).
    • Extend WorkflowClientCallsInterceptor.CancelInput and TerminateInput with firstExecutionRunId; service invoker forwards it to server requests.
  • Invocation/Proxies:
    • Update WorkflowInvocationHandler and WorkflowClientInternalImpl to build stubs from WorkflowTargetOptions and pass targeting flags.
  • Testing/Utilities:
    • Widespread test updates to use WorkflowTargetOptions.
    • New tests validating runId/firstExecutionRunId behavior (WorkflowStubRespectRunIdTest).
    • SDKTestWorkflowRule: add history fetch/assert helpers that accept runId.

Written by Cursor Bugbot for commit f70478d. This will update automatically on new commits. Configure here.

@Quinn-With-Two-Ns Quinn-With-Two-Ns marked this pull request as ready for review November 6, 2025 20:55
@Quinn-With-Two-Ns Quinn-With-Two-Ns requested a review from a team as a code owner November 6, 2025 20:55
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Inconsistent Update Options: Missing firstExecutionRunId Handling

The startUpdate(String updateName, WorkflowUpdateStage waitForStage, Class<R> resultClass, Object... args) method creates UpdateOptions without setting the firstExecutionRunId field, while the update(String updateName, Class<R> resultClass, Object... args) method (line 349) does set it from the stub's firstExecutionRunId field. This inconsistency means that updates started via the convenience method won't respect the firstExecutionRunId targeting, potentially causing incorrect workflow targeting behavior when the workflow has continued-as-new.

temporal-sdk/src/main/java/io/temporal/client/WorkflowStubImpl.java#L360-L370

}
@Override
public <R> WorkflowUpdateHandle<R> startUpdate(
String updateName, WorkflowUpdateStage waitForStage, Class<R> resultClass, Object... args) {
UpdateOptions<R> options =
UpdateOptions.<R>newBuilder()
.setUpdateName(updateName)
.setWaitForStage(waitForStage)
.setResultClass(resultClass)
.setResultType(resultClass)

Fix in Cursor Fix in Web


Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


private void populateExecutionAfterStart(WorkflowExecution startedExecution) {
this.startedExecution.set(startedExecution);
// this.firstExecutionRunId.set(startedExecution.getRunId());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Follow-Through Failure: Immutable First Execution Run ID

The firstExecutionRunId field is declared as final but needs to be populated after workflow start. The commented-out line // this.firstExecutionRunId.set(startedExecution.getRunId()); in populateExecutionAfterStart() reveals this issue - it attempts to call .set() on a String which would fail. Because firstExecutionRunId remains null after starting a workflow, subsequent operations (cancel, terminate, update) will not properly follow the workflow chain using firstExecutionRunId, breaking the intended "follow first run ID" functionality for workflows that continue-as-new.

Fix in Cursor Fix in Web

Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, especially knowing that no code in use today will break (though users may get a bit annoyed when these deprecation warnings pop up). Usually would leave this PR up to other Java reviewers, but thought I'd put my approval on too since I had discussions on the concerns previously.

* @param workflowTargetOptions options that specify target workflow execution.
* @return Stub that implements workflowInterface and can be used to signal or query it.
*/
<T> T newWorkflowStub(Class<T> workflowInterface, WorkflowTargetOptions workflowTargetOptions);
Copy link
Member

@cretz cretz Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantic, but I like WorkflowStubOptions name myself in case we ever want an option unrelated to "workflow target"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah my reason for not using WorkflowStubOptions was because these options are specifically for creating a stub that is attached to a running workflow, instead of a stub that can start a workflow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants