|
| 1 | +Compio 是我目前运营的最大规模的开源社区和项目了。 |
| 2 | + |
| 3 | +## 起因 |
| 4 | + |
| 5 | +2023年的时候,其实只是想要满足一下自己对生态的期望。那时候大家都在讨论,io-uring 是如何与 tokio 不适配,所以需要一个新版的 tokio。但显然 tokio 的开发者们自己并不像贸然推出一个 2.0,担心有很多,比如万一变成了下一个 Python 3.0 怎么办? |
| 6 | + |
| 7 | +一开始我尝试模仿 tokio-uring,写了个 tokio-iocp。但是发现不行,mio 没有暴露 IOCP 的 handle,自己写的话要么卡死要么空转。于是又去尝试改 monoio,但是发现这玩意和 io-uring 耦合得太紧了,要么就是和 mio 耦合的紧。当时甚至在 Windows 上都编译不过去。 |
| 8 | + |
| 9 | +于是决定自己写一个。一开始只想支持 IOCP 和 io-uring 共有的一些 File/Socket IO,发到群里发现反响居然还不错。尤其是 Pop([@George-Miao](https://github.com/George-Miao/)),表现出来了极大的兴趣,并希望来写一个基于 mio 的后端,让这个 runtime 能够跑在 macOS 上。这个项目就一点点做起来了。 |
| 10 | + |
| 11 | +## 社区的形成 |
| 12 | + |
| 13 | +Pop 为 compio 社区贡献良多。除了 [compio-rs](https://github.com/compio-rs/) 是我创建的,第一版的 Logo 是我设计的之外,社区的一切细节都是他完善的。包括项目本身的维护规则,更新版的 Logo 设计,甚至项目[主页](https://compio.rs/)。虽然设定的维护者有五个,但是基本上是我们两个活跃。其他几位: |
| 14 | +* [@bdbai](https://github.com/bdbai) 布丁老师。早期对这个项目有很高的兴趣,同时也是在社区的群莫名解散后,转生的 Rust 中文群的群主。 |
| 15 | +* [@AsakuraMizu](https://github.com/AsakuraMizu) 是 compio-quic 的作者,参加了我作为导师指导的 OSPP 2024。后续一直坚持维护这个 crate,尽职尽责,我深感敬佩。 |
| 16 | +* [@Xuanwo](https://github.com/Xuanwo) 漩涡老师。是 [opendal](https://github.com/apache/opendal) 的作者。Pop 给这个项目贡献了基于 compio 的 filesystem 实现。漩涡老师是更加成熟的开源项目维护者,作为一个过来人指导我们的工作。 |
| 17 | + |
| 18 | +此外还有项目 [compio-py](https://github.com/compio-rs/compio-py),由 [@fantix](https://github.com/fantix/) 主力维护。他在用 compio 实现了一个 Python async runtime 之后联系我们,询问合作意向。我和 Pop 看过他的代码,神清气爽,欣然接受。他们之前似乎有一些担心,如果用了我们的代码,可能会对项目的发展方向有一些干预。但是没关系,其实我们并没有什么特殊的发展方向;能有一个更成熟的项目作指导,对我们也有帮助。 |
| 19 | + |
| 20 | +基于 compio,后来还有项目 [cyper](https://github.com/compio-rs/cyper) 和 [winio](https://github.com/compio-rs/winio)。前者是个基于 hyper 的 HTTP 库,服务端基于 axum。由于 hyper 坚持引入 tokio,我最终决定让 cyper 成为一个单独的项目。 |
| 21 | + |
| 22 | +winio 是个单线程 GUI 库,始于一个愚人节玩笑。我在这一天发布了这样一个 GUI 项目,把 GUI 的事件循环和 async runtime 的循环融合在了一起,这样 GUI 和 IO 都跑在了同一个线程而互不干扰。这本来是一个笑话,但是社区真的有人对它起了兴趣。于是我后面决定持续维护,最终拓展到支持 Win32、WinUI、Qt、GTK、Cocoa 五个后端。这个项目把我大部分之前在 C++ 积累的 GUI 经验移植了过来,是一个对本科经验的总结和发展。 |
| 23 | + |
| 24 | +2026年初,Rust Malaysia 的 Ivan 找到我,问能不能给一个[讲座](https://rust-malaysia.github.io/meetup/)。我自惭于自己的英语口语,于是推荐了 Pop;而 Pop 则要求我做出来 slides 方可。到了讲座那一天,我去约会了,而 Pop 在美国睡大觉,闹钟定晚了一个小时。还好前面还有另一位做讲座,不致出什么大乱子。 |
| 25 | + |
| 26 | +## 一些轶事 |
| 27 | + |
| 28 | +我对以下故事的主人公并无恶意,或者说不值得写在这里,因此隐去部分账号名。 |
| 29 | + |
| 30 | +### Wine |
| 31 | + |
| 32 | +当初写 compio 的一个动力是,tokio 用了 undocumented API,没办法跑在 Wine 里面。结果 compio 写了半天,在 Wine 里面也跑不起来,甚至不知道为什么。 |
| 33 | + |
| 34 | +### 网络服务性能 |
| 35 | + |
| 36 | +actix-web 的作者 [@fafhrd91](https://github.com/fafhrd91) 在我们这里发消息说,他的新项目 ntex 用了 compio 作为 runtime,轻松打败了 tokio。过了不久,他又开始自己写一个 runtime 了,名叫 neon。最近发现又 archive 了,人的精力总是有限的。 |
| 37 | + |
| 38 | +但是我非常感激这位作者,因为他给了我一个强有力的证据证明 compio 的性能强大。求职的时候,compio 是我非常拿得出手的一个项目。 |
| 39 | + |
| 40 | +### 曾用名 |
| 41 | + |
| 42 | +cyper 在独立之前名叫 compio-http。代码文档里面的这个名字直到最近才被发现并更新的。 |
| 43 | + |
| 44 | +### 我忏悔 |
| 45 | + |
| 46 | +Pop 发现 `trait AsyncReadAt` 的 `read_at` 居然接收的是 `&self` 而不是 `&mut self`,破坏了对称性。再一看,作者居然是自己,于是开始怀疑人生。我告诉他其实这是我建议的,不是他的责任。 |
| 47 | + |
| 48 | +### Solaris |
| 49 | + |
| 50 | +有段时间非常好奇其它的 Unix 都是什么样,于是去尝试了 FreeBSD 和 Illumos。最后给 compio 加了 POSIX AIO 的支持,还有 Illumos 的 CI。但是这个 CI 总是因为各种奇妙原因挂掉。问:有谁在用 Illumos 吗?答:我曾经用过,但是其实虚拟机早删了。于是这个 CI 后来改成了只要 clippy 通过就行。 |
| 51 | + |
| 52 | +### Edition 2024 |
| 53 | + |
| 54 | +Edition 2024 最重量级的一条应该是,在 `unsafe` 函数里面调用 `unsafe` 函数,仍然要用 `unsafe` 块包起来,不然就警告。我觉得简直就是脱了裤子放屁,但是布丁老师坚持认为是我的问题。我理解他的意思,但是我并不觉得这是我的问题。`cargo fix` 的解决方案甚至是直接给整个函数体包一个 `unsafe`,所以我觉得这种设计就是多余。 |
| 55 | + |
| 56 | +### Buffer 的所有权之争 |
| 57 | + |
| 58 | +基于完成的运行时,其 IO API 需要 Buffer 的所有权。形式上这个所有权是属于内核的,直到任务完成。任何尝试传引用的设计都会因为 `forget` 的存在导致 UB。 |
| 59 | + |
| 60 | +有一位看名字像是东欧人的用户,一开始很活跃。贡献了几个 PR 之后想要去掉我们对于所有权的限制,因为这导致了一些内存分配无法避免。我们并不同意他的观点,试图纠正,但是最后也没成功。他 fork 了 compio 仓库,改了个名字,删掉了他不喜欢的部分,并发在了 crates.io 上。 |
| 61 | + |
| 62 | +### LLM 其一 |
| 63 | + |
| 64 | +有一位用户问 winio 能否支持 Android,并愿意来贡献代码,我欣然同意。他的 GUI 部分写得有模有样,但是 IO 部分没看懂我的示例。我给他写点示意代码,并用 `// TODO:` 标注应该做什么,他居然直接把这行注释原样粘贴进去。和他的沟通中,我发现了他似乎在用 LLM。我说不要用 edition 2024,至少不要给别的 crate 改成 2024,因为太多和 Android 无关的更改了。于是他用 LLM 劝我说 edition 2024 真的好,解决了许多问题,又说不出个所以然。于是我说不要用 LLM 回复了,用中文也可以。他还是不愿意照我说的更改,最后居然直接关掉了 PR。 |
| 65 | + |
| 66 | +### LLM 其二 |
| 67 | + |
| 68 | +有一位用户想要给 compio-net 加上自定义的 DNS 功能,说是“超级加速”。他的代码也好,PR 描述也好,一看就是 LLM 生成的。我们提出了如下要求: |
| 69 | +* DNS 功能不需要放在 compio-net 里面。没必要去拓展 `ToSocketAddrsAsync`,你自己解析出来直接传 `SocketAddr` 也是一样的。 |
| 70 | +* 不要手写 DNS 协议,维护不过来。建议用 hickory 系列。 |
| 71 | +* 如果要拓展,就像 log 注册 Logger 一样搞个 `Resolver` trait 和注册机制。这样你可以自己实现 `Resolver` 了。 |
| 72 | +* 不要像 rust std 为 `#[global_allocator]` 开洞一样搞什么 `extern "Rust"`,学一下 log 或者 tracing 吧。 |
| 73 | +* 不要动态修改 cargo cache 里面的代码来实现你的 patch,大不了你可以 fork,然后改个名字发布你自己的啊。 |
| 74 | +* 你发布的 crate 太可怕了,还顶着 compio 的名字,搞这种危险操作,改个名字吧。你这样 patch 真的很不好,这不是说 crates.io 是否支持 namespace 的问题,也不是你非要让自己的包出现在 compio 搜索结果的问题。你听信了 LLM 之后还觉得这玩意挺聪明是吧?什么叫还打算写一篇博文让所有人都学会在 build.rs 里面改 cargo cache 来实现 patch? |
| 75 | +* 你还是把这个包删掉吧,不然我们联系 crates.io 官方了。 |
| 76 | + |
| 77 | +最后我们联系了官方,要求他删掉两个 crates,限定期限。他一直不回邮件,于是官方主动删除了这两个。 |
| 78 | + |
| 79 | +### LLM 其三 |
| 80 | + |
| 81 | +Copilot 总觉得 std 的 prelude 里面没有 `Future`。看来它没学会 edition 2024。 |
0 commit comments