plugin: cancellation is only the RPC context — the protocol has no acknowledgement and no quiescence report, and the host neither signals nor waits for a running call, so `Cancel` on a run returns while a plugin is still performing the effect
Open
Nobody has claimed this yet.
design
engine
kind/decision
security
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Written against b015dc6.
Observed behavior
taskService.Execute(pkg/flowstate/v1/plugin/service.go:92-104) wraps the caller's context withcallContextand forwards the call. When the context ends the Connect call returns, and nothing else happens to the process.proto/flowstate/plugin/v1/plugin.protohas no cancel message, no acknowledgement and no quiescence report. Process signalling exists only at instance shutdown (launch.go:495-518: SIGTERM, a grace period, SIGKILL), which is the right place for it and is not the per-call path.- The assessing pass ran a real plugin subprocess that ignored cancellation at
b015dc64. The host returned in about 200 ms; the plugin wrote its effect afterwards. A run-levelCanceltherefore reports finished while the external effect lands later. A companion probe showed the control that does work:retryable=truetogether withunknown_outcome=trueproduced exactly one invocation across five configured attempts. - The timeline records the cancel and nothing about the call's state at that moment (#1658 is the adjacent presentation gap).
Desired outcome
A cancellation contract on the plugin protocol, decided once and reused by #1898's handle:
- A cancel is a request carrying an identity (#1677's attempt id) the plugin can correlate. The plugin answers acknowledged, quiescent or unknown, optionally with a receipt of what it did before stopping.
- The host bounds the wait for that answer (invariant 5) and records the answer on the attempt outcome (#1897's effect field) instead of promising "stopped" from a canceled context. A plugin that does not answer inside the bound is recorded unknown. What the host then does to the process (leave it, signal it) is a configuration decision the catalog names.
- Compensation for a canceled step waits on the answer or on the bound. It never runs concurrently with a plugin still performing the forward effect.
Acceptance criteria
- A plugin conformance case where the plugin ignores cancel: the timeline shows the step's cancel answer as unknown, compensation runs after the bound, and the effects the peer counts match the account (one forward effect, one reversal).
- A cooperating plugin answers quiescent inside the bound and the cancel completes without waiting for it.
- Both drivers through the shared activity; a durable case kills the worker mid-cancel and the replacement does not re-cancel a call already reported quiescent.
Constraints and dependencies
- Parent #1898. Adjacent: #1879, #1677, #1897, #1476, #1658, #1745 (nothing kills a plugin mid-execute), #1864.
- Proto-first: the cancel request and its answer are protocol shapes.
- Compatibility: a plugin built against the current protocol has no cancel handler; the host treats an unimplemented cancel as unknown.
Open questions
- Is cancel a separate RPC on
TaskServiceor a message onExecuteStream? - The same three answers apply to built-in tasks such as
http. Is the contract onTask.EvalInScopefor every task, with plugins as the first driver?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with proto/flowstate/plugin/v1/plugin.proto and taskService.Execute in pkg/flowstate/v1/plugin/service.go, then review the related attempt and effect work in #1898, #1677, and #1897. Resolve the protocol shape and cancellation behavior, then validate the conformance cases for ignored and cooperating plugins, both drivers, and durable worker replacement described in the acceptance criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100