国庆后10月9号,非常开心收到了 Chromium Committer 提名成功的邮件,申请到 Chromium.org 后缀的邮箱。
可能有不少人不了解 Chromium Committer是什么。Chromium是一个开源项目,正如我们所见,很多项目都基于 Chromium构建,包括 chrome浏览器、 electron、vscode 甚至 edge浏览器。任何人都可以给 Chromium 提交代码。当我们提交了一定数目的提交之后,就能邀请3个 Committer 提名自己成为 Chromium Committer。非 Chromium Committer 在提交代码的时候需要至少两个 Committer Review。而 Committer 身份只需要一个 Committer ,同时也能参与 Review 代码。因此 Committer 身份即包含了权限,又包含了更大的期望。
本文主要和大家分享这个过程中一些印象深刻的事情,如果大家感兴趣,后续再分享具体的 Chromium 贡献代码以及成为 Committer 流程。
才发现这是我的个人经历系列文章第三篇 🎉
过程
第一个 CL
今年的8月27号合入了第一个CL(commit list,和MR、PR概念类似):Optimize performance of StyleFromMatchedRulesForElement function 当时是为了解决工作中一个问题。
第一个CL合入永远是最难的,即使代码变更并不复杂。因为不了解合入流程,chromium 对外部贡献代码的态度。再加上时差原因,担心会不会review流程非常慢。但在实际中,这些问题都不存在。Chromium committer review的周期甚至比工作中其他人的code review 周期更快,基本在一个工作日就能得到回复。而且对外部贡献也持有非常欢迎的态度,这让人很受鼓舞。

最紧张的一个 CL
Adjust the NonClientHitTest calculation logic for immersive fullscreen mode on macOS。这个CL的改动很小。当时很快的提交上去了。但是合入之后,很快chromium的CI流程里发现了crash,很快定位我合入的这个CL引入。当时的gardener(每日负责CI流程正确性的员工)很快提起一个reverts。
这个崩溃的原因很简单,就是在web app的browser窗口里,是不存在tab_obverlay_widget的,因此这里有一个空指针问题。当时验证的时候忽略的这个场景。

减少低级错误,在CL 提交review前,仔细检查细节,避免没有测试,没有编译就直接提交,这样才能增强reviewer对自己的信任,这和工作上提交代码的要求是一致的。
最有成就感的一个CL
Replace the query logic inside ProcessMetricsDecorator with QueryAPI
chromium 最早 Performance 模块的数据只有在 ProcessMetricDecrator 内部采集,并且提供了外部触发采集的接口。 之前写过的这篇 chromium resource_attribution 模块的前世今生 文章介绍相关内容,简单来说,就是页面加载完成后,之前通过触发ProcessMetrciDecrator 内部的采集,从而会更新ProcessNode 等节点内部的内存数值。但是后续chromium 改用了新的 resource_atrribution 结构,导致页面加载完成后,ProcessNode 节点内部的内存数值无法立即更新了,因为resource_atrribution 内采集的数据不会通知到ProcessNode内部。
我在 CL的 第一个patch 里提出的方案是,在 resource_atrribution 内部数据采集完成后主动调用 ProcessMetrics的接口,而在ProcessMetrics 内部重新消费这部分数据。这个逻辑有一点耦合,不过我觉得他们都属于perofrmance_manager 模块还好。
Owner 第一次回复我的时候说 ProcessMetricDecrator 使用者很少,更建议以后其他的使用者直接改用 resource_atrribution 模块了。当时有点慌,不过我指出这个模块的必要性,其一该模块处理内存数据给ProcessNode 节点赋值,这个职责无法替代,其次它提供了中心化的内存通知机制,如果没有 ProcessMetricDecrator模块,其他业务都必须要主动采集才能获取内存事件,性能会差一些。
让我欣喜的是,Owner 觉得我说的有道理,同时提出他的修改计划,如果感兴趣可以点击CL查看 Owner回复,非常详细。这也是我第一次认识到,原来在 code review 环节能给出这么详细的修改建议,这对我给别人code review 也是很好的启发。
Onwer 提出两个方案还会询问我认为更喜欢哪个方案,最终和Owner一起完成这个CL的提交。(Owner 完成了前置的关于resource_atrribution 模块的两个CL 提交)
这个CL 是参与和 Owner 讨论最多的一个CL,当时非常有成就感。
有一点打击的CL
Use GetTabsAndCollectionsFromRemovingIndices to move tabs
当时 Chromium m142 上线一个新的功能是分页。这功能熟悉呀,体验了一把后,发现两个标签页构成分页后,如果此时右键标签页的菜单中选择“移动到新窗口”,移动到新窗口后,这个分页的状态会丢失。而如果拖拽分页标签页到新窗口则没有这个问题。
这是因为这两个链路完全是不同的逻辑,拖拽过程中耦合很多UI相关的操作,而菜单中的“移动到新窗口”则是简单实现。我在这个CL中,想把TabModel 内部的一个private 接口GetTabsAndCollectionsFromRemovingIndices变成public ,用于找到选中的一堆标签页中,有哪些标签页是分页属性,Onwer 认为这个可能改动需要进一步讨论,可能不符合Tabs的设计。
这个CL 提交之前,我花了不少时间来研究Tabs的相关逻辑,试图想找到一个改动最小的方式,但是最后代码没有被Owner 允许,这个bug 就先搁置,后续有时间再看看。
申请 Committer
就这样,一个月的时间里,我合入了20个CL,邀请帮我 review次数最多了几个committer,在国庆节假期的前一天申请了提名。等到国庆节结束的第一天,顺利走完了提名流程,获取了committer 权限。
感想
Code Review
Chromium 要求Owner 需要在1~2个工作日进行review,同时Onwer的提名要求也是非常严格的,不仅需要该模块大量贡献,还需要有足够的带宽review代码,还会定期删除不活跃的owner。因此owner一定是对所负责的模块是比较熟悉的。

而且我观察到他们大部分会很热情,比如同意代码的时候,都会主动评论 lgtm, thanks!,或者感谢修复这个问题,感谢提交等等,这对外部贡献者会极大提高积极性。
UT
Chromium 中几乎每个改动都需要有对应的UT覆盖,除非可能涉及到和系统接口交互级别的小问题。这个习惯非常认可,也值得在所有大的线上项目里推广。
工程师文化
工程师有很高的话语权,同时工程师也必须为代码负责。Chromium中的code review规则,每个文件只需要一个Onwer,也就是最好的情况下你只需要一个人同意,你就能合入代码,在大型项目里几乎难以想象。
工程化流程
Chromium 整个工程化非常让人惊艳,从 git source 平台,Gerrit 平台,issue 平台,CI,gold gtest,pingpoint 等等,我觉得做的都非常好。平台的细节考虑很好。
我非常喜欢 issue 平台,让每个问题公开(大部分),可参与,可讨论,可追溯,这比拉群讨论效果好太多了!
Gerrit 平台看着UI交互一般,但是细节很好,比如可以在 CL Review 界面直接编辑、增加、删除变更,而且性能非常多。界面简洁,一切都是为 Code Review 负责。
