最近特别开心!

在周报 2022-45: 使用 sccache 加快 Rust 编译速度 的末尾,我提到希望能把 sscache 的存储后端替换为 Apache OpenDAL:

我给上游提交了一个 proposal: Use opendal to handle the cache storage operations,看看能不能把 sccache 的存储后端访问改为使用 opendal,这样对接存储和调试起来就更方便了~

现在它成真了!今天这篇周报就聊一聊 Sccache 和 OpenDAL 的故事。

不满现状

为了能够在 Databend 的 CI 中快速上线编译缓存的功能,我 fork 了 sscache 并做一些修改,但是在修改的过程中我发现在现有的 codebase 上缝缝补补远不如直接上 opendal 来得效率更高,于是我花了一些时间把 sscache 的 s3 存储后端实现修改成了 opendal。得益于 opendal 良好的日志等基础设施,我很快定位到 AWS 配置侧的一些问题并顺利上线,其中经过和最后的产出已经在 2022-45 的周报中都展开说了。为了便于线上的 CI 使用,我修改了 Cargo.toml,推送了 cccache

编译缓存上线之后运行非常稳定,于是决定就这样用下去。但是这样就面临一个未来长期维护的问题:我对编译这块一窍不通,长期维护类似 sscache 这样的项目肯定是做不到的,且不说实现更多功能,光是应对可能的 bug 都头疼。最好的办法是我能够把现在的修改反馈给上游,从而保证我的服务能够长期稳定的运行。

提出草案

于是我提出了草案:proposal: Use opendal to handle the cache storage operations。在草案中我简单介绍了一下 opendal 是什么,并介绍了使用 OpenDAL 能带来哪些好处:

  • 能够修复很多现存的 BUG(过去手写的 s3/gcs/azblob 实现都比较简单,很多细节没考虑到)
  • 减轻维护者的负担(把具体的服务实现逻辑交给 opendal,sscache 不再需要操心存储的实现细节)
  • 实现服务支持更容易(比如说社区想要原生的 OSS 支持)

维护者的反馈比较中性,提了一些关于性能和目前 OpenDAL 用户有哪些的问题。性能方面我使用 sscache 和 cccache 分别做了 benchmark (我本来以为应该差不多,但是 cccache 要比 sscache 快一些,不知道为什么)。我发现维护者更关心的还是目前 OpenDAL 有哪些用户在用,他们不希望自己的项目依赖一个没几个月就黄了的项目。从维护者的角度来看,依赖的长期维护承诺往往比短时间的些许优势更重要。@sylvestre 的原话是:

Sure, I just don't want to add a critical dependency which could be unmaintained in a few months

主动出击

在收到我的答复之后维护者并没有做出回应,我大胆的决定主动出击:提交了一个使用 OpenDAL 来替换 s3 实现的 PR,用意是秀一下肌肉,证明使用 OpenDAL 真的特别容易,确实能降低维护的负担。可惜这个 Demo PR 没有通过 CI,因为 OpenDAL 最低要求 Rust 1.60 才能进行构建。我本来已经有点丧气了,但是维护者确实非常 Nice,在询问了 OpenDAL MSRV 是多少之后,他们把 sscache 的 MSRV 提升到了 1.60。后来 OpenDAL 的 Demo 顺利通过了所有的 CI,接下来就等待维护者的反馈了。

等待了不少天之后,项目的另一位维护者 @drahnr 出面给了一个正式的回应,指出了使用 OpenDAL 的风险点,提出了一些开放式问题,并总结了使用 OpenDAL 带来的一些好处,整体态度偏向于支持。

这里提出的一些风险点和问题都是开源项目经常要面对的问题,我逐个列出来并聊一下我的回应:

opendal 有很多 sscache 不需要的后端,比如 rocksdb。

这个比较好解决,毕竟 opendal 本身就使用 feature flag 来保证这些有额外依赖的后端不会参与编译。我在回应中解释了这一行为,并且保证 sscache 不会因为这些用不到的后端受到影响。

如何保证 opendal 的后续长期维护?

说实话,我不知道这种问题怎么样回答比较好。毕竟长期维护都是做出来的,靠嘴巴说出来的都不靠谱。更何况我之前就经历过 beyondstorage 全团队裁撤,项目原地停摆的惨剧,所以我对这样的问题十分畏惧。

最后我的回答是坦白说了目前的情况,OpenDAL 是 databend 的核心依赖,由 datafuselabs 团队负责长期维护,并且提到了我们正计划壮大我们的社区以吸引更多的维护者。

API 的稳定性如何保证?是否遵循 semver 的原则?

这个 OpenDAL 一直做的还不错,发版完全遵循 semver 的原则,还维护了 CHANGELOG,感觉这是一个大大的加分项。

MSRV 如何处理?

在 Demo PR 翻车后,我就赶紧给 OpenDAL 设定了 MSRV,并且加入到了 CI 中,在这里就被用到了。

我秀了一下 OpenDAL 的 MSRV Check CI,并且给出了在 1.0 之前不再修改 MSRV 的承诺。

在我回应了上述的所有问题之后,维护者们纷纷点下了自己的 Approve~

目前进展

在迁移完成 s3 之后,我又陆续实现了 azure 和 gcs 的支持:

值得一提的是这两个 PR 都删除了大量的代码,现在为 sscache 增加一个 cache 服务的实现已经简单到只需要几行:

pub struct AzureBlobCache;

impl AzureBlobCache {
    pub fn build(connection_string: &str, container: &str, key_prefix: &str) -> Result<Operator> {
        let mut builder = azblob::Builder::from_connection_string(connection_string)?;
        builder.container(container);
        builder.root(key_prefix);

        Ok(builder.build()?.into())
    }
}

接下来计划给 sscache 增加 OSS 的原生支持~

等 sccache 下一次发版的时候,我就可以彻底干掉 databend CI 中 cccache,使用上游的 sscache 来替换。据说 sscache 同样会被用到 Firefox CI 之中,非常期待,感觉真的在改变世界。

事后感想

  • Show Me The Code:实际的代码比抽象的 Proposal 更能打动人心,所以在提这种大型重构的时候附上一个简单的 PoC 来说明自己的思路往往更容易获得维护者的支持
  • 长期维护的价值:项目的维护者往往更在意项目的长期维护承诺,而不是项目短期的优势和 Fancy 特性
  • 代码风格和文档:这些都是长期的背后工作,但是在项目决策时候却会成为很重要的考量因素,Sccache 看重 OpenDAL 的一点就是丰富的文档和代码比现有的好很多

在 Databend / Greptime / Sccache 之后,OpenDAL 如果再能找到两个社区大用户,并且能找到几位 Committer 的话,感觉就能开始捐赠给 Apache 的工作,有点期待。

冲!