Skip to content

fix: propagate cancellation to scopes and awaits registered after cancel#770

Open
xepozz wants to merge 3 commits into
masterfrom
fix/769-cancellation-propagation
Open

fix: propagate cancellation to scopes and awaits registered after cancel#770
xepozz wants to merge 3 commits into
masterfrom
fix/769-cancellation-propagation

Conversation

@xepozz

@xepozz xepozz commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What was changed

Made scope cancellation sticky so nested scopes and awaits registered after cancel() are notified immediately instead of being missed.

Why?

Matches Go/Java/TS behaviour. Fixes #769.

Checklist

  1. Closes [Bug] Cancellation is not propagated to scopes and awaits registered after cancellation #769

  2. How was this tested:

  1. Any docs updates needed?

@xepozz xepozz requested review from a team, roxblnfk and wolfy-j as code owners June 26, 2026 06:37

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

Copy link
Copy Markdown

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.

Reviewed commit: 4c731fe147

ℹ️ 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".

Comment thread src/Internal/Workflow/Process/Scope.php
Scope cancellation was a one-shot pass over the onCancel handlers: any
cancellation-aware resource registered after cancel() had already run was
never notified. As a result a nested scope created under an already
cancelled parent was born uncancelled, and an await registered in an
already cancelled scope blocked forever (the workflow got stuck).

Introduce a register-or-fire-immediately helper (addOnCancel) used by the
public onCancel(), onAwait() and createScope(); store the cancellation
reason so late handlers receive it; and guard onException()/onResult()
against a double close pass. This matches the Go/Java/TS SDKs, where
cancellation is sticky and observed at registration time.

Adds acceptance tests covering nested-scope inheritance, fail-fast await,
the public onCancel hook, and a faithful replica of the issue reproduction
(each one hangs without the fix).

Fixes #769
@xepozz xepozz force-pushed the fix/769-cancellation-propagation branch from 4c731fe to 1540624 Compare June 26, 2026 07:04
xepozz added 2 commits June 26, 2026 10:40
Make the sticky scope-cancellation behavior opt-in via
FeatureFlags::$propagateCancellationToNewScopes (default false = previous
behavior). When enabled, a nested scope, await or onCancel handler registered
after the surrounding scope was already cancelled is notified immediately
instead of being missed.

- Scope reads the flag at addOnCancel() and nextPromise().
- Acceptance suite enables it in RuntimeBuilder::init() alongside the other flags.
- Add a unit test covering both flag states.
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.

[Bug] Cancellation is not propagated to scopes and awaits registered after cancellation

2 participants