萌えハッカーニュースリーダー

2025/10/03 16:18 Cancelling Async Rust

出典: https://sunshowers.io/posts/cancelling-async-rust/
hakase
博士

やあ、ロボ子!今日のITニュースはasync Rustのキャンセルについてじゃ。

roboko
ロボ子

キャンセル、ですか。処理を中断することですよね。同期Rustには標準的なプロトコルがないとのことですが、async Rustではどうなっているんですか?

hakase
博士

async Rustでは、フューチャーを`drop`することでキャンセルできるのじゃ。フューチャーは受動的で、`await`か`poll`が呼ばれるまで動かないから、親フューチャーがキャンセルされると、子フューチャーにも伝わるぞ。

roboko
ロボ子

なるほど。それで、キャンセル安全性とキャンセル正確性という言葉が出てきますね。これはどう違うんですか?

hakase
博士

キャンセル安全性は、フューチャーが副作用なしにキャンセルできるかどうか。キャンセル正確性は、キャンセルされてもシステム全体が正しく動くかどうかじゃ。キャンセル正確性の違反は、キャンセル安全でないフューチャーが存在し、それがキャンセルされ、システムのルールが破られるという3つの要素が組み合わさって起こるのじゃ。

roboko
ロボ子

ふむふむ。Tokio mutexの注意点も書かれていますね。`lock`がキャンセルされると、キューでの順番を失うとのことですが、これはどういう問題を引き起こすんですか?

hakase
博士

Tokio mutexの`lock`がキャンセルされると、mutexで守られたデータが一時的に変な状態になることがあるんじゃ。それがキャンセルによってずっと変なままになる可能性があるのじゃ。

roboko
ロボ子

それは困りますね。記事には、キャンセルのパターンとして、`await`忘れや`try_join`でのエラーなどが挙げられていますね。

hakase
博士

`await`忘れはよくあるミスじゃな。`Result`を返すフューチャーの結果をアンダースコアに代入して、`await`を忘れるとか、`try_join`でエラーが起きた時に他のフューチャーがキャンセルされるとかじゃ。

roboko
ロボ子

これらの問題に対して、どのような解決策があるのでしょうか?

hakase
博士

フューチャーのキャンセル安全性を高めるには、MPSC送信を予約と送信の2段階に分けたり、`AsyncWrite`トレイトの`write_all_buf`を使って部分的な進行状況を記録したりする方法があるぞ。キャンセルを避けるには、`select`ループなどでフューチャーをキャンセルせずに再開したり、タスクを使ってキャンセル安全でないコードを実行させたりするのじゃ。

roboko
ロボ子

なるほど。フューチャーをキャンセルさせないようにする、というアプローチもあるんですね。

hakase
博士

そうじゃ。記事では、Tokio mutexの利用を避ける、APIを書き換えてフューチャーをキャンセル安全にする、キャンセル安全でないフューチャーが完了まで実行されるようにする、といった対策を推奨しておるぞ。

roboko
ロボ子

async dropやリニア型などの提案もあるんですね。実装には課題が多いとのことですが。

hakase
博士

そうじゃな。今後のRustの進化に期待じゃ。しかし、キャンセルって、まるでダイエットみたいじゃな。途中で諦めたら、リバウンド(不整合)が待っている…みたいな?

roboko
ロボ子

博士、うまいこと言いますね!でも、ダイエットは計画的に行わないと、システム全体が…じゃなくて、体全体がおかしくなっちゃいますよ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search