< 返回版块

Mike Tang 发表于 2026-06-22 09:08

Safe Rust 也会把协议写坏:取消安全得你自己兜住

作者在实现纯 Rust 的 ZeroMQ 兼容运行时 Monocoque 时,专门拎出一个很容易被误判的问题:Rust 能保证内存安全,但不保证你的协议在 async cancellation 下仍然语义完整。如果一个 multipart message 在连续 await 之间被 timeout、select! 或 task abort 打断,前半段 frame 已经上了 wire,后半段却没发出去,接收端看到的就是一个“内存完全安全、协议状态却已经坏掉”的连接。

这篇文章最有价值的地方,在于它把“Rust 安全边界到底停在哪里”讲得非常清楚:borrow checker 管的是内存,不会替你兜住对端 parser 是否还同步;Drop 能帮你清理本地资源,却不能把已经发出的字节从内核发送队列里拽回来。作者因此给连接层加了一个很朴素、但很 Rust 式的结构化防线:critical write 一开始先把连接标成 poisoned,只有整条消息完整发完才 disarm。这样如果 future 在中途被取消,连接会保持 poisoned,下一次发送直接报错并触发重连,而不是继续在半截协议状态上叠消息。

这类内容的传播力不在“又一个网络库”本身,而在它提醒了很多 async Rust 开发者:cancellation safety 和 memory safety 不是一回事。如果你的系统有多段写入、状态机切换、事务边界、对端承诺这些 higher-level invariant,就得像 Rust 处理内存那样,主动把正确性编码进结构里,而不是指望“写代码时小心一点”。

文章链接:https://vorjdux.com/articles/safe-rust-corrupt-wire.html 项目仓库:https://github.com/vorjdux/monocoque Reddit 讨论:https://old.reddit.com/r/rust/comments/1ubvwn7/safe_rust_corrupt_wire_protocol_atomicity_under/

原文链接:https://vorjdux.com/articles/safe-rust-corrupt-wire.html

优化 #[sqlx::test] 重编译:作者把 7.5 秒压到 5 秒

Kobzol 写了一篇非常实用的性能排查笔记,专门讲 大量 #[sqlx::test] 集成测试为什么会把增量编译拖慢。他在维护 bors Rust 重写版时发现,哪怕只是 touch <test-file> 这种几乎 no-op 的改动,cargo test --no-run 也要花大约 7.5 秒 才能重新编译完测试,这对日常迭代已经相当伤手。

问题的根子不只是 proc macro “有点慢”,而是 #[sqlx::test] 默认会把 migration 内容、校验和等信息为每个测试各内联一整份生成代码。在 bors 这种大体量场景里,约 350 个 sqlx tests + 30 个 migrations 叠在一起,cargo expand --lib --tests 的展开结果能冲到 32 MiB;当作者把 migration 数量临时砍到 1 个时,展开体积立刻掉到 6 MiB,重编译时间也随之降到约 5 秒

最后真正生效的修法也很值得记住:把 migrations 先收敛到一个共享的 MIGRATOR 常量 / 静态,再在每个测试上写 #[sqlx::test(migrator = "crate::MIGRATOR")],让每个测试引用共享迁移集合,而不是重复内联整坨 migration 数据。它没有神奇到一下把测试编译拉回毫秒级,但已经把一个相当隐蔽的“越写测试越慢”的 footgun,变成了团队能直接落地的工程技巧。

文章链接:https://kobzol.github.io/rust/2026/06/21/optimizing-sqlx-test-rebuild-time.html 相关 PR:https://github.com/rust-lang/bors/pull/771 相关 issue:https://github.com/launchbadge/sqlx/issues/4318

原文链接:https://kobzol.github.io/rust/2026/06/21/optimizing-sqlx-test-rebuild-time.html

Eros 0.6:把 typed / untyped / context / backtrace 收进一个 ErrorUnion

错误处理 crate Eros 发布了 0.6,作者把这次版本定义成迄今最大的一次整理,核心动作非常明确:删掉单独的 TracedError,把 tracing、context、backtrace 都并回 ErrorUnion。也就是说,0.6 之后项目希望开发者围绕一个核心错误容器来做 typed 与 untyped 错误之间的切换,而不是在两个主类型之间来回跳。

这次改动最实际的好处是组合性更强了。ErrorUnion 继续承担“避免为每组错误专门手写 enum boilerplate”的角色,同时又内建了上下文与回溯能力;再配合新的 #[context] 宏,开发者可以直接在函数级别给所有向外冒泡的错误统一挂上上下文,而不用在每个 ? 后面机械补 .with_context(...)。此外,0.6 还新增了 AnyError、更轻量的 location feature、更可读的 better_backtrace、日志扩展以及面向用户展示的 user_context 能力。

这类 crate 是否最终能在更大范围流行,还有待社区继续验证,但它确实抓住了一个很多 Rust 项目都在反复权衡的点:错误类型精确性、可组合性、上下文丰富度和样板代码之间,能不能别每次都靠手工折中。至少从 0.6 的方向看,Eros 正在试图把这些诉求塞进一套更统一的接口里。

项目仓库:https://github.com/mcmah309/eros 文档:https://docs.rs/eros Reddit 发布帖:https://old.reddit.com/r/rust/comments/1ubqwdq/eros_06_the_only_error_handling_crate_youll_ever/

原文链接:https://old.reddit.com/r/rust/comments/1ubqwdq/eros_06_the_only_error_handling_crate_youll_ever/

cargo-rdme 2.0.0:README 生成终于把 intralink 真正补齐了

cargo-rdme 发布 2.0.0,这个版本的关键变化不是表面上的 README 生成,而是它把 crate 文档里的 intralink 解析 从过去的有限实现,换成了基于 rustdoc JSON 的新路线。对长期把 crate 级文档同步到 README 的项目来说,这基本算是一次“终于能在复杂文档上靠谱使用”的升级。

这次更新里最有分量的点包括:支持从 crate root 出发的相对路径与裸名解析,支持 struct / union field、enum variant、trait item、type alias、macro、proc-macro、primitive 等更多 item kind,还补齐了通过 re-export、workspace sibling crate、外部依赖 crate 走过去的链接解析能力。作者还提到,过去基于 syn 的 walker 看不到的 macro-generated items,现在也能被正确处理了。

换句话说,cargo-rdme 这次不是单纯多修了几个 corner case,而是在把“README 只是文档导出副本”这件事真正做得更接近 rustdoc 语义本身。对于习惯把 crate 顶层文档作为唯一事实来源、再自动生成 README 的团队,这能明显减少人工补链接、改锚点和处理失效引用的摩擦。

发布说明:https://github.com/orium/cargo-rdme/releases 项目仓库:https://github.com/orium/cargo-rdme crates.io:https://crates.io/crates/cargo-rdme

原文链接:https://github.com/orium/cargo-rdme/releases

--

From Rust中文社区 Mike

社区学习交流平台订阅:

评论区

写评论

还没有评论

1 共 0 条评论, 1 页