update: Implement cancellation notification using mpsc::channel

This commit is contained in:
2026-01-10 22:45:01 +09:00
parent 16fda38039
commit a2f53d7879
4 changed files with 192 additions and 148 deletions
+11 -31
View File
@@ -4,7 +4,7 @@ Workerの非同期キャンセル機構についての設計ドキュメント
## 概要
`tokio_util::sync::CancellationToken`を用いて、別タスクからWorkerの実行を安全にキャンセルできる。
`tokio::sync::mpsc`の通知チャネルを用いて、別タスクからWorkerの実行を安全にキャンセルできる。
```rust
let worker = Arc::new(Mutex::new(Worker::new(client)));
@@ -19,15 +19,6 @@ let handle = tokio::spawn(async move {
worker.lock().await.cancel();
```
## キャンセルポイント
キャンセルは以下のタイミングでチェックされる:
1. **ターンループ先頭**`is_cancelled()`で即座にチェック
2. **ストリーム開始前**`client.stream()`呼び出し時
3. **ストリーム受信中**`tokio::select!`で各イベント受信と並行監視
4. **ツール実行中**`join_all()`と並行監視
## キャンセル時の処理フロー
```
@@ -42,11 +33,10 @@ Err(WorkerError::Cancelled) // エラー返却
## API
| メソッド | 説明 |
| ---------------------- | --------------------------------------------------------- |
| `cancel()` | キャンセルをトリガー |
| `is_cancelled()` | キャンセル状態を確認 |
| `cancellation_token()` | トークンへの参照を取得(`clone()`してタスク間で共有可能) |
| メソッド | 説明 |
| ----------------- | ------------------------------ |
| `cancel()` | キャンセルをトリガー |
| `cancel_sender()` | キャンセル通知用のSenderを取得 |
## on_abort フック
@@ -69,22 +59,12 @@ async fn on_abort(&self, reason: &str) -> Result<(), HookError> {
## 既知の問題
### 1. キャンセルトークンの再利用不可
### on_abort の発火基準
`CancellationToken`は一度キャンセルされると永続的にキャンセル状態になる。
同じWorkerインスタンスで再度`run()`を呼ぶと即座に`Cancelled`エラーになる。
`on_abort`**interrupt(中断)** された場合に必ず発火する。
**対応案:**
interrupt の例:
- `run()`開始時に新しいトークンを生成する
- `reset_cancellation()`メソッドを提供する
### 2. Sync バウンドの追加(破壊的変更)
`tokio::select!`使用のため、Handler/Scope型に`Sync`バウンドを追加した。
既存のユーザーコードで`Sync`未実装の型を使用している場合、コンパイルエラーになる。
### 3. エラー時のon_abort呼び出し
現在、`on_abort`はキャンセルとフックAbort時のみ呼ばれる。
ストリームエラー等のその他エラー時には呼ばれないため、一貫性に欠ける可能性がある。
- `WorkerError::Cancelled`(キャンセル)
- `WorkerError::Aborted`(フックによるAbort
- ストリーム/ツール/クライアント/Hook の各種エラーで処理が中断された場合