テクノロジー · 実用ガイド

cancel した task の await で CancelledError?controller の shutdown を飲み込まない

child cancellation 完了と外部 controller cancellation は同時に起こります。ownership、finally cleanup、outcome collection、propagation test を分けます。

Asyncio cancellation origin 図
オリジナルイラスト:child と controller cancellation を区別。 Watch at Ease

child cancellation 完了と外部 controller cancellation は同時に起こります。ownership、finally cleanup、outcome collection、propagation test を分けます。

CancelledError は BaseException で cleanup 後は通常再送出します。 Task.cancel は request で受理保証ではありません。

1. task owner と trigger を列挙

controller、owned children、cancel source、sibling fate を記録し、except-pass から始めません。

await child の CancelledError は child 終了または controller 外部 cancel で、type だけでは origin 不明です。

2. child cleanup は finally

child resources は try/finally で解放し cancellation を通常再送出します。cleanup 内 await も取消され得ます。

async finalization は小さな boundary を設け、shield を unbounded shutdown にしません。

3. TaskGroup と gather を選択

全 child を scope が所有し sibling failure を連動するなら TaskGroup。context exit が全て待ちます。

independent child outcome は gather(return_exceptions=True) で集約でき、gather 自身の cancel は伝播します。

4. controller cancellation を保持

await child の blanket catch を避けます。manual なら child state と current_task().cancelling を記録し controller cancel は再送出します。

state を消すためだけに uncancel しません。suppression は例外的で意図的な decision です。

5. simultaneous case を test

child-only、controller-only、same-turn を test し cleanup、states、propagation を assert します。

exit では owned tasks だけ audit し、pending と unretrieved exception がないことを確認します。

Asyncio shutdown primitive 図
オリジナルイラスト:ownership と outer cancellation を保持。 Watch at Ease