Summary
CancellationToken is the most pervasive abstraction in the workspace (550 lines across 74 files) with no written rules, and usage has drifted:
clone() vs child_token() is ~141:52. A clone shares the same scope, so any holder calling .cancel() tears down the whole tree; children are the right default for subordinate tasks. Disciplined child_token use exists only in dkg; large subsystems (tracker: 19 CT lines, validatorapi: 25, sse: 15) use zero.
drop_guard() appears exactly twice (privkeylock.rs#L123, wire.rs#L1140). Everywhere else an early-returning task leaves siblings running with no signal.
- Orphan tokens with no parent link (cancel never propagates from the caller):
prioritiser's quit, deadliner's internal token, dkg's lock_ct.
- Three vocabularies coexist:
select! { _ = ct.cancelled() => ... } (~41 sites), ct.run_until_cancelled(fut) (24 sites, nearly all in one file), and the third-party cancellation crate's callback API in the QBFT core (goes away with draft 05a).
- Naming (
ct, cancel, cancellation, token, quit) and by-value vs &CancellationToken passing are unstandardized, forcing gratuitous clones at boundaries.
Proposed change
Update the current set of conventions: when to child_token vs clone, when a task owns a DropGuard, one preferred waiting idiom, parameter naming and passing. Then sweep the flagged sites — in particular giving subordinate tasks child tokens and auditing the orphan tokens for missed shutdown propagation.
Acceptance
Documented rules plus a pass over tracker/validatorapi/sse/prioritiser aligning them; no orphan token without a comment explaining its independence.
Summary
CancellationTokenis the most pervasive abstraction in the workspace (550 lines across 74 files) with no written rules, and usage has drifted:clone()vschild_token()is ~141:52. A clone shares the same scope, so any holder calling.cancel()tears down the whole tree; children are the right default for subordinate tasks. Disciplinedchild_tokenuse exists only indkg; large subsystems (tracker: 19 CT lines, validatorapi: 25, sse: 15) use zero.drop_guard()appears exactly twice (privkeylock.rs#L123,wire.rs#L1140). Everywhere else an early-returning task leaves siblings running with no signal.prioritiser'squit, deadliner's internal token, dkg'slock_ct.select! { _ = ct.cancelled() => ... }(~41 sites),ct.run_until_cancelled(fut)(24 sites, nearly all in one file), and the third-partycancellationcrate's callback API in the QBFT core (goes away with draft05a).ct,cancel,cancellation,token,quit) and by-value vs&CancellationTokenpassing are unstandardized, forcing gratuitous clones at boundaries.Proposed change
Update the current set of conventions: when to
child_tokenvs clone, when a task owns aDropGuard, one preferred waiting idiom, parameter naming and passing. Then sweep the flagged sites — in particular giving subordinate tasks child tokens and auditing the orphan tokens for missed shutdown propagation.Acceptance
Documented rules plus a pass over tracker/validatorapi/sse/prioritiser aligning them; no orphan token without a comment explaining its independence.