关键事实
Future 在 .await 点可能被取消。若状态更新分布在多个 await 之间,就可能出现“写了一半”的业务状态。
设计原则
- 把副作用集中在单一提交点。
- 在可取消区间只做纯计算或幂等准备。
- 对外部系统写入使用幂等键。
反例与修正
// 反例:先扣库存再写订单,两个 await 中间可被取消
reserve_stock().await?;
create_order().await?;
// 修正:准备阶段无副作用,最后一次性提交
let plan = build_plan().await?;
commit(plan).await?;
工程策略
- 为关键流程增加“中断注入测试”。
- 对每个 await 标注取消后的状态语义。
- 引入补偿任务清理孤儿状态。
小结
异步取消是默认行为,不是异常路径。把 cancellation safety 当作接口契约的一部分,才能避免线上出现“偶发且不可复现”的脏状态。