rust-async-task-design について
Rust の非同期タスク設計を支援するスキルです。所有権、サスペンドポイント、ブロッキング処理、キャンセルを明確にする手順とレビュー項目を提供します。
主な機能
- 01サスペンドポイントと保持状態の確認
- 02生成タスクの所有権とハンドル管理
- 03ブロッキング処理と CPU 負荷の高い処理の分離
- 04await をまたぐロックと借用の確認
- 05キャンセルと失敗経路の確認
活用シーン
- 01Tokio のタスク生成のレビュー
- 02await をまたぐロックの検出
- 03ブロッキング処理の非同期タスクからの分離
- 04タイムアウトとキャンセル動作のテスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ lvtd-llc/ skills --skill rust-async-task-designインストール後、Claude Code で/rust-async-task-designを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlreferences/async-runtime-patterns.md
詳細
Rust 非同期タスクの設計
このスキルを使うと、Rust の非同期コードにおけるタスクの所有権、中断ポイント、ブロッキング処理、キャンセルを明確にできます。非同期処理は並行処理モデルであり、スレッドのデフォルトの代替手段でも、パフォーマンスを保証するものでもありません。
基本的なワークフロー
- 非同期処理の境界を特定します。ランタイムのエントリーポイント、ハンドラー、クライアント呼び出し、ストリーム、バックグラウンドタスク、トレイトメソッドなどが該当します。
- すべての
.awaitに、中断の可能性があることを示します。その間、どの状態が保持されるかを確認します。 - タスクが必要なものをすべて所有でき、選択したランタイムでその Future が
Send + 'staticである場合にのみ、tokio::spawn(async move { ... })を使います。 - タスクの成功、パニック、キャンセル、シャットダウンが重要な場合は、
JoinHandleを保持します。重要な処理を暗黙のうちに切り離してはなりません。 - ブロッキング I/O や CPU 負荷の高い処理を非同期タスクに含めないでください。処理内容に応じて、非同期 API、
spawn_blocking、Rayon、専用スレッドを使います。 - 同期的な
MutexGuard、RefCellの借用、Sendではない値を.awaitをまたいで保持しないでください。 - タイムアウト、キャンセル、チャネルの切断、タスクの失敗が動作に影響する場合は、それらの経路をテストします。
ランタイムのルール
タスクの起動、非同期コードでの共有状態、ブロッキング処理を確認する際は、references/async-runtime-patterns.md を参照してください。
- 非同期コードで
std::sync::Mutexを使うのは、競合が少なく、.awaitをまたがない短いクリティカルセクションに限ります。 - ロックを
.awaitをまたいで保持する必要がある場合は、tokio::sync::Mutexを使います。ただし、まず状態をタスクの内側に移し、メッセージでやり取りする方法を検討してください。 - 最終的に完了するブロッキング処理には
spawn_blockingを使います。CPU 負荷の高い処理では並列度を制限してください。Tokio のブロッキングプールは大きくなることがあります。 - 処理時間に上限を設けるには、
tokio::time::timeoutまたは明示的なキャンセルトークンを使います。 select!は慎重に使ってください。Future をドロップすると、その処理がキャンセルされることがあります。I/O や一部だけ完了した処理で使う前に、キャンセル安全性を確認します。
非同期トレイトのルール
- 呼び出し側が返される Future に制約を追加する必要がない場合、プライベートトレイトや静的ディスパッチでは、トレイトのネイティブな
async fnを使って問題ありません。 SendFuture が必要なパブリックトレイトでは、通常、メソッドをfn name(...) -> impl Future<Output = T> + Sendと記述するか、trait-variantを使ってローカル版とSend版を提供します。- 動的ディスパッチが必要なパブリックトレイトでは、通常、
Pin<Box<dyn Future<Output = T> + Send + '_>>のような、明示的にボックス化した Future の戻り値型が必要です。依存関係や割り当てのトレードオフを許容できる場合に限り、利便性を高める手段としてasync-traitを使います。 - トレイトが意図的に特定のランタイムに依存するものでない限り、エグゼキューター固有の型をトレイトの外部に公開しないでください。
レビューチェックリスト
- ロックや借用が意図せず
.awaitをまたいでいない。 - 起動したタスクが
async moveで入力を所有している。 - 重要な
JoinHandleが、シャットダウン時にawait、監視、または中断されている。 - ブロッキング処理が分離され、実行量に上限が設けられている。
- エラー処理でコンテキストが保持され、
JoinErrorやタイムアウトに関する雑音に変わっていない。
コメント
Markdown 対応