背景
Tokio 里 select! 和超时很常用,但取消发生在任意 await 点,任务可能停在中间状态。
实践建议
- 把副作用操作放在不可分割阶段
- 写操作尽量幂等
- 关键路径加补偿或重试机制
tokio::select! {
_ = shutdown.recv() => {
tracing::info!("cancelled");
}
res = do_commit_work() => {
res?;
}
}
总结
取消安全本质是状态机设计,不是语法问题。
异步代码能停下来不难,停得干净才难。