テクノロジー · 実用ガイド
asyncio.gatherが例外を出しても兄弟Taskが動く?TaskGroupか所有Taskの取消を選ぶ
gatherは最初の例外を伝えるが兄弟を取消さない。一緒に失敗させるならTaskGroup、選択的ならTaskを保持して取消と終了待ちを行う。

asyncio.gatherは集約であり全員失敗のスコープではない。最初の例外が呼出側へ届いても未完了の兄弟は走る。捕捉時点でgather Futureが完了済みならcancelはfalseである。
実行前に失敗方針を決める。同一整合性境界ならPython 3.11+のTaskGroupを使い、選択的ならTaskを自分で作り取消と清掃待ちを行う。
1. 失敗後も動くことを再現
短時間で失敗する協程と後で印を残す協程をgatherする。例外後にcancelしループを継続し、falseと印を確認する。
CPython 3.12.14では遅い兄弟が完了し、TaskGroup版では取消された。
2. APIより先に方針を選ぶ
一つの論理結果を共同更新し一つの失敗で残りが無効ならTaskGroupを使う。
独立作業や回復可能な失敗ならTaskの所有権を保持する。
3. Python 3.11+はTaskGroup
同じTaskGroupから全兄弟を作る。最初の非取消例外で残りを取消し清掃後にExceptionGroupを出す。
async with外でexcept*を使いCancelledErrorは飲み込まない。
4. 選択的方針は所有、取消、待機、再送出
create_taskで句柄を保持し、対象だけcancelする。return_exceptions=Trueで全所有Taskの清掃を待つ。
待機後は元の例外を再送出するか結果を明示する。
5. 協調取消を試験
CancelledErrorはawait点で入る。try/finallyで資源を解放し通常は再送出する。
gather継続、TaskGroup取消、手動待機、親の外部取消と副作用記録を確認する。
