Dispatch cancel command for standalone activities - #10218
Open
rkannan82 wants to merge 30 commits into
Open
Conversation
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
May 11, 2026 19:26
77e0a54 to
d68c034
Compare
rkannan82
changed the base branch from
main
to
kannan/move-dispatch-response-to-error
May 11, 2026 19:26
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
June 10, 2026 23:28
7b46553 to
47b1c94
Compare
rkannan82
changed the base branch from
kannan/move-dispatch-response-to-error
to
kannan/extract-worker-commands-dispatch
June 11, 2026 17:11
rkannan82
added a commit
that referenced
this pull request
Jun 24, 2026
## What Move `dispatchResponseToError` and `startOperationResponseToError` from `service/history` to `common/nexus` as exported functions. ## Why To reuse in standalone activities. See [PR](#10218) ## How did you test it? Existing unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
rkannan82
changed the base branch from
kannan/extract-worker-commands-dispatch
to
main
June 24, 2026 19:26
stephanos
pushed a commit
that referenced
this pull request
Jun 25, 2026
## What Move `dispatchResponseToError` and `startOperationResponseToError` from `service/history` to `common/nexus` as exported functions. ## Why To reuse in standalone activities. See [PR](#10218) ## How did you test it? Existing unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Move the entire workerCommandsTaskDispatcher from service/history to common/workercommands so it can be reused by CHASM standalone activities (which cannot import service/history due to circular dependency). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
June 26, 2026 01:25
a87bac3 to
f5221d3
Compare
When a standalone activity is cancelled or terminated while running on a worker, proactively notify the worker via a cancel command dispatched through the Nexus worker commands control queue. This is best-effort — the activity will eventually time out if the worker doesn't respond. Key changes: - Add CancelCommandDispatchTask side-effect task and handler - Store started-time ComponentRef in ActivityAttemptState so cancel tokens are byte-identical to poll tokens (SDK does exact byte match) - Set Execution field in AddActivityTaskRequest for correct WorkflowId/RunId - Add NewStandaloneActivityTaskToken to common/tasktoken - Wire cancel dispatch on cancel-requested and terminate transitions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
June 26, 2026 02:01
f5221d3 to
77d9d48
Compare
The functional test TestDispatchCancelCommandToWorker already validates that the cancel command token matches the poll token end-to-end. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
June 26, 2026 19:05
6f8f5ff to
c9c7da3
Compare
rkannan82
commented
Jun 26, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l-commands' into kannan/standalone-activity-cancel-commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Unpack fx.In options into individual handler struct fields, matching the callback invocationTaskHandler pattern. Simplify NewStandaloneActivityTaskToken to take a single activityID since workflowID and activityID are always identical for standalone activities. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture the ComponentRef from RecordActivityTaskStartedRequest instead of ctx.Ref(a). This is the exact ref matching used to build the poll token, so the cancel command token is guaranteed to match even if the component is mutated between dispatch and start. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the cancel_command_dispatched flag and associated logic. Standby handling will be addressed via a new CHASM abstraction instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
trangnguyenkp
pushed a commit
to trangnguyenkp/temporal
that referenced
this pull request
Jul 9, 2026
## What Move `dispatchResponseToError` and `startOperationResponseToError` from `service/history` to `common/nexus` as exported functions. ## Why To reuse in standalone activities. See [PR](temporalio#10218) ## How did you test it? Existing unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
trangnguyenkp
pushed a commit
to trangnguyenkp/temporal
that referenced
this pull request
Jul 9, 2026
…emporalio#10849) ## What Moves `worker_commands_task_dispatcher.go` from `service/history` to `common/workercommands/dispatcher.go` and exports its types. The call site in `outbound_queue_active_task_executor.go` is updated to use the new import path. ## Why To reuse this in [PR](temporalio#10218) that sends cancel commands for standalone activities. ## How did you test it? - Existing unit tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Now that CHASM exposes attempt count via TaskAttributes, use it to: - Drop the cancel command dispatch task after MaxTaskAttempts in Validate - Pass the real attempt count to the dispatcher instead of hardcoded 1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use TaskInvocation (not TaskAttributes) in Validate, since Attempt is only available there. Keep dispatcher call with attempt=1 since max attempts are enforced in Validate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Standalone activities route responses via ComponentRef, not WorkflowId or RunId. Remove the Execution field from AddActivityTaskRequest and simplify NewStandaloneActivityTaskToken to pass empty strings, matching what matching produces in the poll token. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Standalone activities don't have a parent workflow. Remove the Execution field from AddActivityTaskRequest and leave WorkflowId/RunId empty in NewStandaloneActivityTaskToken. Matching gets ActivityId from the RecordActivityTaskStartedResponse, not from AddActivityTaskRequest, so the poll and cancel command tokens remain consistent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Unit tests for cancelCommandDispatchTaskHandler.Validate: status checks and max attempt enforcement - TransitionStarted test: verify ComponentRef and WorkerControlTaskQueue are captured from RecordActivityTaskStartedRequest - E2e test: terminate dispatches cancel command to worker control queue Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l-commands' into kannan/standalone-activity-cancel-commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
awln-temporal
approved these changes
Jul 14, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rkannan82
force-pushed
the
kannan/standalone-activity-cancel-commands
branch
from
July 14, 2026 22:02
950ab6d to
aee246f
Compare
spkane31
pushed a commit
that referenced
this pull request
Jul 15, 2026
## What Move `dispatchResponseToError` and `startOperationResponseToError` from `service/history` to `common/nexus` as exported functions. ## Why To reuse in standalone activities. See [PR](#10218) ## How did you test it? Existing unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
spkane31
pushed a commit
that referenced
this pull request
Jul 15, 2026
…10849) ## What Moves `worker_commands_task_dispatcher.go` from `service/history` to `common/workercommands/dispatcher.go` and exports its types. The call site in `outbound_queue_active_task_executor.go` is updated to use the new import path. ## Why To reuse this in [PR](#10218) that sends cancel commands for standalone activities. ## How did you test it? - Existing unit tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ivity-cancel-commands
Now that #11066 moved the attempt check to callers, the dispatcher no longer takes an attempt parameter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
What
Send activity cancellation commands for standalone activities to the worker. When a standalone activity is cancelled or terminated while running on a worker, the server proactively notifies the worker via a cancel command through the Nexus worker commands control queue.
Key changes:
ComponentReffrom matching'sRecordActivityTaskStartedRequestin the attempt state. This is the exact ref matching used to build the poll token, ensuring the cancel command token matches.CancelCommandDispatchTaskas a CHASM side-effect task, and dispatch it using the existingworkercommands.DispatcherAPI.TaskInvocation.Attemptto enforce max retry attempts in Validate, preventing infinite retries on standby clusters.ComponentRefas the sole routing identifier —WorkflowId/RunIdare left empty since they don't apply.Why
Without proactive notification, cancelled standalone activities would only stop when they use activity heartbeats, or wait till they time out.
How did you test it?
🤖 Generated with Claude Code