Skip to content

Conversation

andresilva
Copy link
Collaborator

@andresilva andresilva commented Oct 9, 2025

Cloning a runtime context before its parent task spawned captured the parent's aborter list, so aborting the parent left those earlier clones running. This PR introduces a Children helper that keeps aborter lists in sync across clones: each Context::clone branches the dependency tree, and spawn propagates the fresh list to every branch before the task starts. Both deterministic and tokio runtimes now use this helper, ensuring abort cascades stay correct even when contexts are cloned ahead of time.

Related #1849
Related #1666 - With this PR the tests there pass without any changes (I promise!)

Copy link

cloudflare-workers-and-pages bot commented Oct 9, 2025

Deploying monorepo with  Cloudflare Pages  Cloudflare Pages

Latest commit: 902d0e1
Status: ✅  Deploy successful!
Preview URL: https://adb0a1d1.monorepo-eu0.pages.dev
Branch Preview URL: https://andre-context-dependency-tre.monorepo-eu0.pages.dev

View logs

@patrick-ogrady
Copy link
Contributor

Both deterministic and tokio runtimes now use this helper, ensuring abort cascades stay correct even when contexts are cloned ahead of time.

Does this implicitly enforce spawn happens in order (down the tree)?

// children tree, any clones created before this call (for example, actors built
// during initialization) also retarget to `children`. The previous list is kept
// so we can link this task back to its parent.
let previous = self.children.replace(children.clone());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a test that this still works if spawns are called in the wrong order (child before parent)?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should also add a test for the case that some intermediate layer is never spawned (this could happen if there is an extra clone on the path?)

@patrick-ogrady
Copy link
Contributor

patrick-ogrady commented Oct 10, 2025

As discussed, a simplifying technique for this problem could be storing the task tree in executor rather than in each context (this ensures any tasks spawned in the heirarchy will be aborted, even if there are gaps).

If we are supervised and end up getting called (after some parent has been aborted), we can just not schedule the inner future.

// while the parent keeps its original abort handles. The returned triple provides
// the optional parent supervisor list (if the child is supervised), the new child's
// aborter list, and the branch that should be installed on the child context.
let (parent_children, children, child_children) =
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Could probably do with better names for these variables.

Copy link

codecov bot commented Oct 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.20%. Comparing base (d6bd338) to head (902d0e1).

@@           Coverage Diff           @@
##             main    #1850   +/-   ##
=======================================
  Coverage   92.19%   92.20%           
=======================================
  Files         305      305           
  Lines       79457    79538   +81     
=======================================
+ Hits        73255    73335   +80     
- Misses       6202     6203    +1     
Files with missing lines Coverage Δ
runtime/src/deterministic.rs 95.78% <100.00%> (+0.04%) ⬆️
runtime/src/tokio/runtime.rs 82.43% <100.00%> (+0.48%) ⬆️
runtime/src/utils/handle.rs 94.54% <100.00%> (+1.68%) ⬆️
runtime/src/utils/mod.rs 88.98% <ø> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d6bd338...902d0e1. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

struct ChildrenInner {
/// Abort handles for tasks spawned directly under this branch. Whenever the branch
/// completes or is aborted we drain this list and cancel descendants.
owned: Arc<Mutex<Vec<Aborter>>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

If we have Mutex<> around ChildrenInner, why do we need one here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose its because we destructure ChildrenInner and pass it around.

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

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants