每周技巧 #90:退役的标志
本节阅读量:本文翻译自 Abseil 官网的 Tip of the Week #90: Retired Flags。
原文最初作为 TotW #90 发布于 2015 年 3 月 19 日。
我们对命令行 flag 的(误)用中,有一件令人沮丧的事:很难安全地从二进制和生产服务器中移除一个 flag(可以重温 技巧 #45 看一些令人沮丧的误用)。问题在哪里?如果你指定了一个不再定义的 flag,二进制就无法启动,因此移除 flag 可能需要协调 C++ 代码与你的作业启动脚本和配置。
在某些情况下,这种协调可能非常有挑战性(基于二进制版本调整生产代码)。要是有更好的办法就好了!
确实有。不久前,我们在 C++ 命令行 flags 系统中加入了一个新概念,叫“退役 flag”(ABSL_RETIRED_FLAG)。
退役 flag 不会在 C++ 中创建符号(不再有可以依赖的 FLAGS_some_flag 全局变量),不会出现在 --help 中,但在命令行中指定时会被接受(不过会记录一个 ERROR)。这样一来,代码不再使用的 flag 就可以被“退役”,从而把 C++ 改动和生产配置改动分离开。等配置改动全部清理完成后,就可以彻底移除这个退役 flag。
退役 flag 被设计成可用于许多情况(包括涉及跨仓库非原子提交要求的情况)。一个非常简单的 flag 退役过程可以像下面这样逐步进行:
-
从代码中移除对
FLAGS_frobber的使用。如果你遵循 https://abseil.io/tips/45 的建议,主要从
main()使用 flag,那么这应该很容易做到,也很容易检查。 -
修改 flag 定义,把它退役。也就是说:
1ABSL_FLAG(type, frobber, "default", "Which frobber to use?");应该变成:
1ABSL_RETIRED_FLAG(type, frobber, "default", "retired"); -
等待二进制发布。等所有 serving cell 中的所有作业都调用新二进制后,就可以继续。
-
从生产配置中移除该 flag。等搜索相关生产配置确认没有 frobber flag 命中后,就可以继续。
-
移除退役 flag。
我们已经成功完成过非常复杂的 flag 移除:推动这项工作的动机示例,是移除定义在一个遗留内部文件系统中的 flag。它更复杂,因为这些 flag 定义在库中,因此被许多二进制使用。根据我们看到的情况,即使是最复杂的 flag 移除,也可以借助这个系统安全完成。所以,下次当你想知道如何安全移除一个 flag 时,请考虑先让它退役,然后一步步推进。