Deno `deno_maybe_sync` 解析:一套让同一份 Rust 代码同时支持多线程与单线程运行时的可选同步抽象层

发布时间:2026/10/28 18:27:35

Deno `deno_maybe_sync` 解析:一套让同一份 Rust 代码同时支持多线程与单线程运行时的可选同步抽象层 Denodeno_maybe_sync解析一套让同一份 Rust 代码同时支持多线程与单线程运行时的可选同步抽象层【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/denolibs/maybe_sync中的deno_maybe_sync是 Deno 工作区里一个极简但关键的“同步开关”库通过一个syncCargo feature让Arc/Rc、OnceLock/OnceCell、DashMap/HashMap等并发结构与单线程结构以完全相同的类型名MaybeArc、MaybeOnceLock、MaybeDashMap等出现在下游代码里。读完本文你将理解 Deno 与 Deno Deploy 两种运行时对线程模型的不同假设掌握这个库两个实现分支的逐类型对应关系、API 子集边界以及 feature 在下游 crate 中的链式传递方式。这个库解决什么问题README 对它的定位只有两句话但点明了动机OptionallySyncstructures used in Deno. Deno uses theSyncfeature, while Deno Deploy doesnt, so thats why we have this code.即Deno CLI 本身启用Syncfeature而 Deno Deploy 不使用Sync。两者的差异可以这样理解Deno CLI多线程运行时共享状态需要std::sync::Arc、std::sync::OnceLock等跨线程原语类型必须满足Send Sync。Deno Deploy从 clippy.toml 中对url::Url::to_file_path等 API 的禁用理由Use deno_path_util instead so it works in Wasm可以看出该形态面向 Wasm/无操作系统的执行环境在单线程世界里Arc的重量级引用计数、OnceLock的原子开销以及DashMap的分片锁都是不必要的负担用Rc、OnceCell、RefCellHashMap即可。如果没有这层抽象libs/resolver、libs/config、libs/cache_dir等被两种运行时共享的 crate 就必须各维护一份代码。deno_maybe_sync的做法是下游代码只写MaybeArcT编译器根据 feature 决定它到底绑定到哪个具体类型。包结构与 feature 开关Cargo.toml 定义了全部开关逻辑[features] sync [dashmap] [dependencies] dashmap { workspace true, optional true } rustc-hash.workspace true要点syncfeature 唯一作用就是启用可选依赖dashmapdashmap仅在多线程分支下参与编译rustc-hash两个分支都会使用见下文FxBuildHasher默认参数根工作区 Cargo.toml 中以deno_maybe_sync { version 0.45.0, path ./libs/maybe_sync }声明并把它列入 workspace members供所有下游 crate 以路径依赖方式引用。整个库的入口是 lib.rspub use inner::*;之后inner模块被#[cfg(feature sync)]与#[cfg(not(feature sync))]切分成两套互斥实现。多线程分支直接透传标准并发原语开启syncfeature 时lib.rs所有Maybe*类型都只是标准库/第三方并发类型的别名Maybe*名称实际绑定说明MaybeSendcore::marker::Send直接是标准库 marker traitMaybeSynccore::marker::Sync直接是标准库 marker traitMaybeArcTstd::sync::ArcT原子引用计数MaybeOnceLockTstd::sync::OnceLockT跨线程的一次性初始化MaybeDashMapK, V, Sdashmap::DashMapK, V, S分片锁并发 Map默认 hasher 为rustc_hash::FxBuildHasherMaybeDashSetT, Sdashmap::DashSetT, S分片锁并发 Set注意两个细节marker trait 也是 Maybe 的一部分。下游代码里写where T: MaybeSync的约束在多线程形态下就是真正的Sync约束编译器会严格检查。FxBuildHasher作为默认 hasher。两个Maybe*集合类型都把S的默认参数写成rustc_hash::FxBuildHasherlib.rs避免对短字符串 key如 URL、路径这类在 Deno 中大量出现的 key使用成本更高的 SipHash。该分支顶部有#![allow(clippy::disallowed_types, reason implementation the rule says to use)]——工作区 Clippy 规则本意是禁止下游直接用这些类型而本库正是被允许使用的那个实现属于典型的守门人例外写法。单线程分支同名字面、不同语义未开启sync时lib.rs四个概念分别退化为单线程等价物MaybeArc与MaybeSend/MaybeSyncpub use std::rc::Rc as MaybeArc; pub trait MaybeSync {} implT MaybeSync for T where T: ?Sized {} pub trait MaybeSend {} implT MaybeSend for T where T: ?Sized {}MaybeArc从Arc换成Rc非原子引用计数单线程下更快。MaybeSync/MaybeSend被重定义为对任意T都成立的空 marker traitblanket impl。这意味着单线程构建下where T: MaybeSync约束自动通过、不产生任何检查——因为单线程世界里根本不存在跨线程共享的合法性问题。这是feature 改变类型语义而非feature 改变代码路径的关键体现。MaybeOnceLock绑定到std::cell::OnceCell与OnceLock的初始化语义get_or_init等在下游视角保持一致只是去掉了原子性。MaybeDashMapRefCellHashMap的 API 子集pub struct MaybeDashMapK, V, S FxBuildHasher(RefCellHashMapK, V, S);它只暴露了多线程分支DashMap的一小部分方法lib.rs方法单线程分支签名语义get- OptionRefa, V借用HashMap::get结果返回Ref而非DashMapRefinsert- OptionV返回被替换的旧值remove- Option(K, V)内部用remove_entry实现clear/len—直通下游代码如果要跨两种形态编译就只能在交集内使用这些方法——DashMap的entry、iter、retain等在单线程分支并不存在这是使用本库时最实际的 API 约束。get的实现值得注意Ref::filter_map(self.0.borrow(), |map| map.get(key)).ok()用Ref::filter_map把key 不存在折叠进Option同时保留了Ref的借用语义防止调用方在持有读引用期间被borrow_mut。此外两个类型都手写Debugimpl只转发到内部集合目的是不强制S: Debug——注释里写明原因正是FxBuildHasher并不实现Debug。MaybeDashSetRefCellHashSetpub struct MaybeDashSetV, S FxBuildHasher(RefCellstd::collections::HashSetV, S);单线程分支只实现了insertlib.rs交集比MaybeDashMap更小使用时同样需要以它为准。自由函数new_rc与new_arclib.rs 末尾提供两个#[inline]构造函数pub fn new_rcT(value: T) - MaybeArcT { MaybeArc::new(value) } pub fn new_arcT(value: T) - std::sync::ArcT { std::sync::Arc::new(value) }new_rc的返回类型随 feature 变化ArcT或RcT供下游统一写堆分配一份共享状态new_arc则始终返回真正的std::sync::Arc用于那些即便在单线程形态下也必须保持Arc语义的场景。下游如何使用feature 链式传递在 Deno 工作区里deno_maybe_sync是线程模型的唯一事实来源各 crate 通过 feature 依赖把它向上传递。典型链条均来自各 crate 的Cargo.tomllibs/package_json/Cargo.tomlsync [deno_maybe_sync/sync]libs/config/Cargo.tomlsync [deno_maybe_sync/sync, deno_package_json/sync]libs/node_resolver/Cargo.tomlsync [deno_maybe_sync/sync, deno_package_json/sync]libs/resolver/Cargo.tomlfeature 列表中直接启用deno_maybe_sync/syncext/fs/Cargo.tomlsync_fs [deno_maybe_sync/sync]即最终二进制Deno CLI在自己侧打开顶层 feature层层透传至deno_maybe_sync而 Deno Deploy 侧不打开整棵依赖树就编译出Rc/OnceCell/RefCell版本无需任何代码分叉。下游代码的写法也印证了这一点例如 libs/resolver/collections.rs 中type UrlRc deno_maybe_sync::MaybeArcUrl;同一行代码在两种形态下分别编译为ArcUrl和RcUrl。实际引用方遍布模块解析与缓存体系包括libs/resolver/lib.rs、factory.rs、graph.rs、lockfile.rs、cjs/analyzer/等、libs/cache_dir/cache.rs、local.rs、memory.rs以及ext/fs/lib.rs、interface.rs、std_fs.rs。配套约束clippy.toml 揭示的无 OS目标clippy.toml 与本库的 feature 设计互为印证。它通过disallowed-methods禁止直接调用一大类标准库 API理由集中在两类文件系统/环境/时间操作std::fs::*、std::path::Path::metadata、std::env::var、std::time::SystemTime::now等一律要求 should be done using sys_traits即经抽象 trait 访问从而让同一份代码能在无操作系统的构建里替换底层实现URL 与文件路径互转url::Url::to_file_path、from_file_path、from_directory_path要求 Use deno_path_util instead so it works in Wasm。这解释了为什么单线程形态与Wasm 形态在本仓库中基本是同义词不要求Sync的前提就是代码运行在单线程、无原生系统调用的环境里而 clippy 规则负责在编译期守住这条边界。总结一个 feature 换来的双运行时同源代码deno_maybe_sync的全部设计可以浓缩为三行下游代码只面对MaybeArc、MaybeOnceLock、MaybeSend/MaybeSync、MaybeDashMap/MaybeDashSet这一组中性名称syncfeature 打开时它们是Arc/OnceLock/真Send/Sync/DashMap/DashSet关闭时退化为Rc/OnceCell/恒真 marker/RefCellHashMap/RefCellHashSetfeature 经由libs/config、libs/node_resolver、libs/resolver、ext/fs等 crate 向上传递使 Deno CLI 与 Deno Deploy 共享同一套解析、缓存与配置代码。若要在当前仓库中继续深入建议的阅读顺序是先读本目录 lib.rs约 140 行全文即实现再看 libs/resolver/collections.rs 了解MaybeArc的真实用法最后对照 libs/resolver/Cargo.toml 观察 feature 如何声明与启用。需要留意的前提是该库与 0.45.0 版本的工作区配套feature 名称与Maybe*类型集合以当前仓库源码为准。【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/28 1:55:45

嵌入式人机界面如何选串口屏?从RS485通信到Giraffe IDE的落地指南

做嵌入式人机界面时,很多项目遇到的第一个门槛不是显示效果本身,而是主控资源不够。如果单片机还要跑业务逻辑、通信协议和算法,再为一块 5 寸屏维护复杂 UI,开发量和维护成本会迅速膨胀。串口屏的解法是给屏幕单独配一颗 GUI 主控…

2026/10/28 4:22:53

STM32F407驱动4.3寸电容屏:FSMC时序、触摸驱动与LVGL移植实战

简介:本资源是面向嵌入式开发初学者与STM32进阶工程师的完整驱动实践方案,聚焦STM32F4系列(尤其F407)对4.3英寸800480分辨率TFT LCD电容触摸屏的底层驱动实现,解决高分辨率显示控制与多点触控交互集成这一典型工程难点…

2026/10/28 7:18:33

Perplexity、Fable与GPT-5.6 Terra:核心Agent+子代理架构详解

最近 AI 圈有个组合比较引人注意:Perplexity、Fable、GPT-5.6 Terra,再加上“子代理”这类关键词。很多人第一反应是:Perplexity 不是做 AI 搜索的吗,怎么突然和“计算机”扯上关系了? 如果只看表面,很容易…

2026/10/28 18:23:55

Delphi 12 安装 Indy 10.6.3.3 与阻塞式 Socket 实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 18:23:55

STM32时钟系统深度解析:RCC寄存器配置与72MHz实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 18:18:53

验证MYSQL安装成功+安装的前提

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑