关于 rust-async-task-design
面向 Rust 开发者的异步编程技能,涵盖任务所有权、挂起点、阻塞工作与取消。它提供工作流程和检查清单,帮助明确并发设计。
主要功能
- 01检查挂起点及其持有状态
- 02管理生成任务的所有权与句柄
- 03隔离阻塞和 CPU 密集型工作
- 04检查跨越 await 的锁与借用
- 05检查取消和失败路径
适用场景
- 01审查 Tokio 任务生成方式
- 02查找跨越 await 的锁
- 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 异步代码明确任务所有权、挂起点、阻塞工作和取消行为。异步是一种并发模型,并非线程的默认替代方案,也不保证性能。
核心工作流
- 确定异步边界:运行时入口点、处理程序、客户端调用、流、后台任务或 trait 方法。
- 将每个
.await标记为可能的挂起点。检查有哪些状态会跨越该挂起点。 - 仅当任务能够拥有所需的一切,且其 future 在所选运行时上满足
Send + 'static时,才使用tokio::spawn(async move { ... })。 - 如果任务的成功、panic、取消或关闭情况很重要,就保留
JoinHandle。不要默默分离重要工作。 - 不要在异步任务中执行阻塞 IO 和 CPU 密集型工作。根据工作负载使用异步 API、
spawn_blocking、Rayon 或专用线程。 - 不要让同步
MutexGuard、RefCell借用或非Send值跨越.await。 - 如果超时、取消、通道关闭和任务失败会影响行为,就为这些情况添加测试。
运行时规则
审核任务生成、异步代码中的共享状态或阻塞工作时,请阅读 references/async-runtime-patterns.md。
- 仅当临界区较短、竞争较少且不会跨越
.await时,才在异步代码中使用std::sync::Mutex。 - 如果锁必须跨越
.await,则使用tokio::sync::Mutex,但应先考虑将状态放到一个任务中,并通过消息与其交互。 - 对最终会完成的阻塞操作使用
spawn_blocking。限制 CPU 密集型工作的并行度;Tokio 的阻塞线程池可能会扩展得很大。 - 对有界操作使用
tokio::time::timeout或显式取消令牌。 - 谨慎使用
select!:丢弃一个 future 可能会取消它。在 IO 操作或部分完成的工作周围使用时,请检查其取消安全性。
异步 trait 规则
- 如果是私有 trait 和静态分派,且调用方不需要为返回的 future 添加约束,那么在 trait 中使用原生
async fn没问题。 - 如果需要
Sendfuture,公共 trait 通常应将方法写为fn name(...) -> impl Future<Output = T> + Send,或使用trait-variant提供本地和Send两种变体。 - 如果需要动态分派,公共 trait 通常需要显式的装箱 future 返回类型,例如
Pin<Box<dyn Future<Output = T> + Send + '_>>。只有在依赖和分配方面的权衡可以接受时,才将async-trait用作提升易用性的封装层。 - 除非 trait 有意绑定到特定运行时,否则应避免在 trait 中暴露特定执行器的类型。
审核清单
- 没有锁或借用意外跨越
.await。 - 生成的任务通过
async move拥有其输入。 - 重要的
JoinHandle会在关闭时等待、监控或中止。 - 阻塞工作已隔离并受到限制。
- 错误路径会保留上下文,而不是退化为
JoinError或超时噪声。
评论
支持 Markdown