乐趣区

关于rust:如何在开源项目中做重构

作者:xuanwo@Datafuse-Labs

最近实现了 Databend 存储模块的大重构,在不阻塞现有性能开发的前提下,根本无痛的实现了性能的实现。本文总结了我集体的一些教训,冀望可能带来一些启发。


做重构不易,尤其是在一个相当沉闷的 codebase 上。Databend 当初每周有 40+ PR 被 merge,在过来的一周中有 800+ 文件产生了变更,代码减少了 21K 行,删除了 12K 行。在这样的代码库上,毕全功于一役的代价是高到可怕的。所以在整个重构的生命周期中,咱们都须要跟社区放弃亲密沟通,让社区晓得你想做什么,怎么做,当初的停顿如何。在这一次的重构中我总结出了如下教训:

撰写提案

正如 The Apache Way 所说:Community over code。一个好的开源我的项目不仅仅是由代码组成,抛开开源共同体谈形象的技术和代码是没有意义的。因而向开源我的项目提交大型的变更之前,咱们必须要论述分明本人的想法,解释动机,让开源共同体晓得本人想做什么,想怎么做。

这些落到纸面上的文档在探讨时可能补充信息,欠缺想法,构建出更好的设计。从长期角度看,文档可能帮忙后来者了解过后为什么要提出这样的设计,从而防止反复踩坑。不仅如此,一份好的设计文档往往还可能影响、启发其余开源我的项目的设计,从而促成整个行业提高。

@tison 在 如何参加 Apache 我的项目社区 提到过:

对于任何 non-trivial 的改变,都须要有肯定的形容来表明动机;对于大的改变,更须要设计文档来留存记忆。人的记忆不是永恒的,总会遗记最后的时候本人为什么做某一件事件,设计文档的积淀对于社区解脱人的不确定性演变有至关重要的作用。

在本次重构之前,我在 Databend 的 Discussions 中向整体社区成员公开地论述了本人的愿景和心愿: proposal: Vision of Databend DAL。而后跟多位相干的模块的维护者获得了沟通,达成了宽泛的一致意见,之后才开始了本次的重构。我认为跟维护者获得统一是十分要害的步骤,否则极有可能呈现工作到一半时维护者发现想法抵触导致工作被终止或者重来,这是十分丧气的。

此外,开源共同体实质上都在奉行 基于开源奉献 的精英主义准则。贡献者必须要通过奉献来证实本人的价值,获得社区的信赖,而后能力推广本人的主张。所以在提出一个大型改变之前,最好先通过参加一些 good first issue 退出到社区中来,理解社区的标准,相熟社区的编译流程,跟模块的维护者保持联系,建设本人在社区中的影响力。在本次重构之前,我帮忙 Databend 社区实现了新的社区官网上线,革新了全新的 CI Pipeline,跟各个模块的维护者根本都刷了个脸熟。

值得注意的是,Databend 像很多新生的开源我的项目一样,还没有欠缺的提案流程,然而这并不意味着咱们就不能或者不须要提交提案。提交 Proposal 的意义就在于跟社区沟通达成统一,不要被模式所解放,只有能最终达成统一就是能够承受的。与此同时,开源我的项目的治理流程自身也在不断完善和演进。事实上,绝大多数我的项目中正式的提案解决流程正是在社区在一直的承受和解决一份份提案的过程中被搭建起来的。

创立 Tracking Issue

在提交了 Proposal 通过之后,最好能创立一个 Tracking Issues 来跟踪 Proposal 的实现状况。

通常咱们会命名成 Tracking Issue for Xxxx,在这个 Issue 中,咱们须要

  • 链接到之前通过的 Proposal 以便于社区成员理解当前工作的上下文
  • 列出本人的工作打算和 TODO List
  • 随进度更新本人的停顿

除了本人的布局安顿之外,还有一种比拟常见的状况是在 PR review 时维护者常常会提出一些后续的改良倡议,咱们能够对立汇总到 Tracking Issue 中来。

Tracking Issues 的意义在于让社区理解以后的停顿并在适时的时候提供须要的帮忙,社区通过查看 Tracking Issue 就能理解 Proposal 目前是处于沉闷开发还是停滞状态,对 Proposal 实现感兴趣的成员也可能通过 Tracking Issue 反馈本人的想法和参加志愿。

在本次重构中,我通过 Tracking issue for Vision of Databend DAL 来跟踪 Proposal 的停顿状况。除了本人的布局的个性之外,我还记录了很多维护者 review 时提供的反馈意见和一些长期的不成熟想法,这些都是将来我的项目能够改良的方向。

拆分 Pull Requests

在实现 Proposal 的时候要依据理论的状况拆分 PR。

PR 拆的太细会给维护者带来额定的累赘,由此产生的大量无用 CI 工作也不利于低碳环保;PR 太大则会导致维护者难以 review,要么草草通过了事,要么迟迟没人 review,这都不利于工作的推动,更不用说大 PR 有更大的概率呈现代码抵触。

每个 PR 该当是一个残缺的个体,能够实现某个特定的指标。以我的两个 PR 为例:

  • dal2: Eliminate type parameters in DAL:打消 DAL 中的类型参数
  • dal2: Implement DAL Layer support:实现 DAL Layer 反对

这里的每个 PR 都只做了一件很明确的事件,维护者通过浏览 PR 的题目和形容就能迅速了解这个 PR 在做什么,这样代码 review 的时候就会事倍功半。

PR 的拆分更多依赖于集体的教训和格调,当怎么拆分比拟好时,能够请维护者帮忙出主见。

放弃专一

在实现 Proposal 的过程中须要放弃专一,不要无限度地延拓工作边界。

实现过程中往往会遇到一些新的待解决问题,又往往与以后的 Proposal 相关联,此时最好采纳最小化的准则,优先保障以后的 Proposal 可能胜利交付。一方面,人的能力是有极限的,不能因为以后负责实现这个 proposal,就去承当所有相干的工作,这往往会导致相干模块的工作都阻塞在本人身上,没有最大化地利用来自开源共同体的力量;另一方面,望山跑死马,无限度地拓展工作边界会导致本人的成绩没有一个清晰的交付工夫点,本人会感到精力在一直被耗尽,社区的急躁和期待也在一直地被消磨。

所以咱们须要放弃专一,致力抗拒新性能和新个性的引诱,优先保障以后的 proposal 中承诺的性能交付。等到 proposal 齐全实现并合并之后,给本人放一个小假,而后再开启新的 proposal 并实现,如此循环。有交付才有激励,才有能源去实现更多的工作,不要设定一个永远无奈企及的指标。

寻求帮忙

在实现 Proposal 的过程中,要踊跃地跟社区交换,向社区寻求帮忙。

时刻牢记咱们不是一个人在战斗,咱们背地是整个开源社区。遇到问题的时候不要一个人闷头苦想,踊跃的向社区寻求帮忙,小到语言个性(尤其是你在应用 Rust 时),大到功能模块。一个问题查了一天材料也没有后果,问问维护者往往能给出更正当的解决方案或者可行的 work around。

不必放心裸露本人的有余,大家都是这么过去的。开源共同体中的成员往往利益趋向于统一,所以维护者有志愿有能源来帮忙解决问题。我最喜爱的 Rust 开发者 dtolnay 就是一个极为优良的榜样:在 PR Add try_reserve and try_reserve_exact for OsString 中,dtolnay 给出了粗疏而明确的 review 意见,帮忙我了解了这部分逻辑的细节。

在实现 query: Replace dal with dal2, let’s rock! 的过程中,我遇到了一个想了很久也没有想明确的问题,于是提交了评论 向维护者 @dantengsky 寻求帮忙。在评论中,我给出了问题的形容,残缺的 backtrace,还有最简化的复现步骤。在 @dantengsky 的帮忙下,这个问题很快就失去了解决。

浏览 发问的智慧 会很有帮忙,然而齐全没读过也没关系,外围的要旨是相互尊重。不要发号施令,也不要低声下气。咱们尊重维护者是因为他们过往的奉献而非现在的社区位置,相比于大佬之类的无意义恭维,在解决问题后的一声 Thanks 往往更让人感到开心。


总得来说,在开源我的项目中做大规模的重构,最重要的就是放弃交换,继续沟通。撰写 Proposal,创立 Tracking Issue,拆分 PRs 都是为了交换服务的。再此基础上,咱们须要留神一些实现中的技巧,放弃专一,并适时地向社区寻求帮忙。以上就是我在本次重构中总结进去的一些教训,心愿可能帮忙到你,欢送在评论区一起交换~

对于咱们

Databend 是一个应用 Rust 研发、开源、齐全面向云架构的旧式数仓,提供极速的弹性扩大能力,致力于打造按需、按量的 Data Cloud 产品体验。

「Datafuse Labs」成立于 2021 年 3 月,是开源我的项目 Databend 的背地团队,团队在云原生数据库畛域有着丰盛的工程教训,同时也是数据库开源社区沉闷贡献者,目前在中国、美国、新加坡均设有研发核心,专一于前沿技术畛域的翻新与实际,以及 Databend 开源生态、社区构建。

退出移动版