Node.js Feature Flags — Fallback Defaults, Caching, and 60-Second Polling

本文为原文前 6,000 字符的节选翻译,完整内容请查看原文。

Use Node.js feature flags only when fallback defaults and caching let the notification worker make a safe decision without reaching the flag service. For an edtech rollout, that means a disabled default in code, a short-lived last-known value, and a polling interval derived from the rollback deadline. TL;DR: Set the risky delivery path to false by default. Poll outside the delivery loop. Accept cached data only inside a stated freshness window, then fall back to the code default. If a provider change must stop within 60 seconds, the poll and cache policy must make that outcome possible even during startup and API failure.

仅当回退默认值和缓存能让通知工作进程在不访问标志服务的情况下做出安全决策时,才使用 Node.js 功能标志。对于教育科技产品的发布,这意味着代码中应包含禁用的默认值、短生命周期的最后已知值,以及根据回滚截止日期推导出的轮询间隔。简而言之:默认将高风险的交付路径设置为 false。在交付循环之外进行轮询。仅在声明的新鲜度窗口内接受缓存数据,之后回退到代码默认值。如果提供商的变更必须在 60 秒内停止,那么轮询和缓存策略必须确保即使在启动和 API 故障期间也能实现该结果。

Option Best fit for this rollback job Trade-off to accept LaunchDarkly A team choosing a dedicated feature-management product Adds a vendor SDK and its lifecycle Unleash A team that values an open-source feature-flag option Operating it yourself creates another production duty ConfigCat A team that wants a dedicated hosted flag product Still requires an explicit application fallback policy Infrai A small service that prefers plain REST and no flag SDK Polling only, with governance handled separately

选项最适合此回滚任务的场景需要接受的权衡
LaunchDarkly选择专用功能管理产品的团队增加了供应商 SDK 及其生命周期管理
Unleash重视开源功能标志选项的团队自行运维会增加额外的生产职责
ConfigCat需要专用托管标志产品的团队仍需明确的应用回退策略
Infrai偏好纯 REST 且无需标志 SDK 的小型服务仅支持轮询,治理需单独处理

Recommendation: choose by rollback safety, not by the length of the feature list. For one Node.js notification service, a thin REST integration is reasonable when a 60-second propagation budget is sufficient. Choose a dedicated flag platform when audit history, evaluation statistics, flag dependencies, or deletion recovery are requirements rather than future wishes.

建议:根据回滚安全性而非功能列表的长度进行选择。对于某个 Node.js 通知服务,当 60 秒的传播预算足够时,轻量级的 REST 集成是合理的。当审计历史、评估统计、标志依赖关系或删除恢复是当前需求而非未来愿景时,请选择专用标志平台。

How should Node.js feature flags handle fallback defaults and caching? The dangerous design is a network read in the hot path. A class reminder reaches the worker, the worker asks for provider_v2, and delivery now depends on two services instead of one. A slow or failed flag request can hold up the reminder even though the established provider is healthy. Invert that dependency. The delivery path reads a local snapshot synchronously. A background poller refreshes it. If the process has never completed a valid poll, it uses the default compiled beside the decision. In this case, false keeps reminders on the established provider.

Node.js 功能标志应如何处理回退默认值和缓存?危险的设计是在热路径中进行网络读取。当课程提醒到达工作进程时,工作进程请求 provider_v2,此时交付过程便依赖于两个服务而非一个。即使既有的提供商运行正常,缓慢或失败的标志请求也可能阻塞提醒发送。应反转这种依赖关系。交付路径应同步读取本地快照,并由后台轮询器进行刷新。如果进程从未完成有效的轮询,则使用决策代码旁编译的默认值。在这种情况下,false 值可确保提醒保留在既有的提供商上。

Defaults are executable rollback policy. The cache is different. A cached true says that the experimental provider was enabled at an earlier time. It does not say that true is safe forever. Model three states: fresh value, stale value, and no valid value. Fresh data may drive delivery. Stale or absent data resolves to the code default once the declared freshness window closes. For a 60-second rollback budget, a useful starting policy is a 15-second poll and a 45-second maximum cache age. Those numbers are design inputs, not measured latency. They leave room for a missed poll while preventing an old true from surviving indefinitely.

默认值是可执行的回滚策略。缓存则不同。缓存的 true 表示实验性提供商在较早的时间点被启用,但这并不意味着 true 永远安全。应建模三种状态:新鲜值、陈旧值和无有效值。新鲜数据可驱动交付。一旦声明的新鲜度窗口关闭,陈旧或缺失的数据将回退到代码默认值。对于 60 秒的回滚预算,一个实用的初始策略是 15 秒的轮询间隔和 45 秒的最大缓存有效期。这些数字是设计输入,而非测量延迟。它们为错过轮询留出了余地,同时防止了过期的 true 值无限期存在。

Four Node.js processes would each poll unless the deployment coordinates them, so request volume grows with process count. Polling is the only client refresh model for Infrai flags. It also has no flag-change audit log, evaluation statistics, parent-child dependency model, or recycle bin for deleted flags. A release checklist can cover a small number of flags; it is not a substitute for governance when many people can change production behavior.

除非部署时进行了协调,否则四个 Node.js 进程将各自进行轮询,因此请求量会随进程数量增加。轮询是 Infrai 标志唯一的客户端刷新模型。它也没有标志变更审计日志、评估统计、父子依赖模型或已删除标志的回收站。发布检查清单可以覆盖少量标志;但当多人可以更改生产行为时,它不能替代治理。

Make rollback a state machine, not a Boolean. The code below keeps the HTTP adapter outside the rollback state machine because the verified material does not specify the value response envelope. The adapter must be generated from the discovery schema for the verified value route before deployment. Unknown JSON must never enable the risky path.

将回滚做成状态机,而不是布尔值。下面的代码将 HTTP 适配器保持在回滚状态机之外,因为验证材料并未指定值响应的封装格式。适配器必须在部署前根据已验证值路由的发现模式生成。未知的 JSON 绝不能启用高风险路径。

[Code block omitted for brevity]

[代码块省略]

This is intentionally boring. A failed refresh retains the snapshot, but the read function independently rejects it after 45 seconds. The adapter uses an explicit GET, reads the key and verif

这特意设计得非常枯燥。刷新失败会保留快照,但读取函数会在 45 秒后独立地拒绝它。适配器使用显式的 GET 请求,读取密钥并进行验证。