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

Introduces WorkflowTargetOptions-based APIs and updates stubs to target the specified workflow/run (with optional firstExecutionRunId), deprecating legacy constructors and updating requests and tests accordingly.

  • Client API:
    • Add WorkflowTargetOptions (with workflowId, runId, firstExecutionRunId).
    • New overloads: newWorkflowStub(Class, WorkflowTargetOptions) and newUntypedWorkflowStub(WorkflowTargetOptions[, Optional<String>]).
    • Deprecate newWorkflowStub(Class, String, Optional<String>) and untyped variants taking WorkflowExecution/runId.
  • Stub targeting behavior:
    • Ensure stubs respect provided runId; add legacyTargeting flag to preserve old behavior for deprecated paths.
    • Plumb firstExecutionRunId through WorkflowStubImpl and WorkflowInvocationHandler for signals/cancel/terminate/updates.
    • Use exact execution when targeting; legacy paths strip runId to follow chains.
  • Requests/Interceptors:
    • Extend WorkflowClientCallsInterceptor.CancelInput/TerminateInput and Root invoker to send firstExecutionRunId.
    • Include firstExecutionRunId in Update request inputs.
  • Tests:
    • Update usages to new APIs; add WorkflowStubRespectRunIdTest validating signal/query/cancel/terminate behavior across continue-as-new.
    • Minor test helpers: allow fetching/asserting history by (workflowId, runId).

Written by Cursor Bugbot for commit 1776365. 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

Copy link
Contributor

@maciejdudko maciejdudko left a comment

Choose a reason for hiding this comment

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

One small comment, I'll approve after it gets resolved.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as spam.

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.

3 participants