mcpField
R
rust-async-task-design

rust-async-task-design

github.com/lvtd-llc開発161 回インストール8 週間前に更新
リポジトリ

rust-async-task-design について

Rust の非同期タスク設計を支援するスキルです。所有権、サスペンドポイント、ブロッキング処理、キャンセルを明確にする手順とレビュー項目を提供します。

主な機能

  1. 01サスペンドポイントと保持状態の確認
  2. 02生成タスクの所有権とハンドル管理
  3. 03ブロッキング処理と CPU 負荷の高い処理の分離
  4. 04await をまたぐロックと借用の確認
  5. 05キャンセルと失敗経路の確認

活用シーン

  1. 01Tokio のタスク生成のレビュー
  2. 02await をまたぐロックの検出
  3. 03ブロッキング処理の非同期タスクからの分離
  4. 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 の非同期コードにおけるタスクの所有権、中断ポイント、ブロッキング処理、キャンセルを明確にできます。非同期処理は並行処理モデルであり、スレッドのデフォルトの代替手段でも、パフォーマンスを保証するものでもありません。

基本的なワークフロー

  1. 非同期処理の境界を特定します。ランタイムのエントリーポイント、ハンドラー、クライアント呼び出し、ストリーム、バックグラウンドタスク、トレイトメソッドなどが該当します。
  2. すべての .await に、中断の可能性があることを示します。その間、どの状態が保持されるかを確認します。
  3. タスクが必要なものをすべて所有でき、選択したランタイムでその Future が Send + 'static である場合にのみ、tokio::spawn(async move { ... }) を使います。
  4. タスクの成功、パニック、キャンセル、シャットダウンが重要な場合は、JoinHandle を保持します。重要な処理を暗黙のうちに切り離してはなりません。
  5. ブロッキング I/O や CPU 負荷の高い処理を非同期タスクに含めないでください。処理内容に応じて、非同期 API、spawn_blocking、Rayon、専用スレッドを使います。
  6. 同期的な MutexGuard、RefCell の借用、Send ではない値を .await をまたいで保持しないでください。
  7. タイムアウト、キャンセル、チャネルの切断、タスクの失敗が動作に影響する場合は、それらの経路をテストします。

ランタイムのルール

タスクの起動、非同期コードでの共有状態、ブロッキング処理を確認する際は、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 を使って問題ありません。
  • Send Future が必要なパブリックトレイトでは、通常、メソッドを 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 やタイムアウトに関する雑音に変わっていない。

コメント