← 全部文章

FourA 周报,2026年8月21日至8月28日

用量统计现已覆盖账单周期涉及的每个小时,组织会向相关人员通报事件进展,Browser 修复了文件句柄泄露问题。

亮点

现在用量统计会覆盖计费周期涉及的每一个小时,因此“用量与限制”页面上的额度总额从周期的第一秒起便完整覆盖。组织功能补齐了上周缺失的通知流程:被添加的用户会收到通知,负责付费的所有者也会收到通知,角色选择器也明确说明了各项权限。此外,我们梳理了 Dashboard,重写了那些原本站在我们角度而非用户角度表述的提示信息。

新增功能

计费周期内的每个小时都计入统计

你的计费周期始于注册的那一秒。用量则按固定时间段聚合统计。这两者几乎从不对齐,因此将二者映射的计算逻辑必须在边界处做到分毫不差。

现在已经实现。周期会被划分为各部分当前可用最高精度的完整时间桶,不拆分,也不重复计算。读取用量的三处逻辑统一共用同一套底层实现,这才是根本的修复方案。同一套计算逻辑维护三份副本,必然会导致其中某一处出错。

你会注意到的变化:“用量与限制”页面上的所有数值都会比上周略微上升。流量完全相同,只是统计更完整。没有人会因为这次调整而超出套餐限额。由于这套计算逻辑同样用于控制配额,因此双向保持准确非常重要。

加入组织不再静默无声

组织功能已于上周上线,你可以添加同事、为其分配角色,并允许他们使用由公司付费的密钥。但当时无法自动通知对方。表单下方的提示建议你自己去通知。

现在会发送两封邮件。被添加者会收到一封,注明组织名称、添加者、其角色权限,以及非预期加入时的退出途径。所有者会在有人加入时收到一封,因为组织的密钥由所有者的套餐付费,多一个人消耗额度直接关系到其实际成本,而非单纯的客套通知。点击按钮的操作者不会收到邮件,你不需要为自己的操作接收回执。

所有者通知在两种场景下均会触发:直接添加用户,以及用户在首次登录时接受邀请(此时无需其他操作人介入,用户自行完成进入)。

角色权限也附带了明确说明。选择器下方的提示行会随着你的选择实时更新,“角色”列也添加了涵盖包括所有者在内全部三种角色的提示工具。在完全不清楚权限的情况下选择“Member”还是“Admin”,往往会导致人们默认滥发 Admin 权限。

一步添加同事

输入邮箱地址,点击“添加”。如果对方已经是 FourA 用户,会立即加入。如果不是,我们会发送邀请邮件,对方在登录后即可加入。无论哪种情况,使用同一个按钮、同样的确认流程和反馈,页面仅用一句话同时概括这两种结果,无需单独判断所输入的邮箱属于哪种情况。

第二个对话框已被移除,之前用来提示某个地址是否已注册账户的回复也同样被移除。某个任意邮箱是否在我们这里注册,不再是一个我们会回答的问题。

Dashboard 不再直接向日志写入内容

"Failed to fetch organizations" 本应是供我们内部排查的日志,此前却直接展示在了用户面前。

其中 35 处提示已改为用户可操作的语句,例如 "We couldn't load your organizations. Try again in a moment."。所有面向用户阅读的文案都采用了更自然的缩写。"Invalid member id" 及其类似提示现在会直接说明具体错误,而不是直接抛出变量名。此前容易与这些提示混淆的控制台输出保持不变,因为那些确实是供我们调试使用的。通过代码调用我们时返回的 API 结构校验,以及 Dashboard 用于分支判断的机器可读代码,也同样保持原样。

邮件文案也进行了同样的优化。邀请陌生人加入 "an organization" 的邮件通常会被直接扔进垃圾箱,因此你所设定的具体名称重新回到了邮件中:账户、密钥、组织以及邀请人。客户输入的自定义文本依然不会出现在我们发送的任何邮件中。

底层实现

Browser 此前在每个渲染会话中都会泄漏一个文件句柄,且问题并非出在我们的代码中。某个上游依赖项关闭了其两个日志句柄中的一个,随后提前返回并跳过了第二个,但这仅在调用方提供自定义 profile 目录时才会发生。我们在每次启动时都会提供该目录,导致这一泄漏必然发生且持续存在。

补丁包装了该单一方法,而不是直接 fork 该依赖项。它首先运行原始逻辑,仅在句柄仍处于打开状态时才介入处理。这样一来,一旦上游将关闭句柄的代码移至 return 语句之前,我们的补丁就会静默变为无操作。测试用例会在安装补丁前复现该泄漏,从而明确该文件防御的具体问题,而不仅仅是断言一切正常。

实际效果:长时间运行的 Browser 实例能够保持其处理能力,而不会随着会话的累积而耗尽资源。如果你希望控制这些会话在线路上的传输特征,browser profiles 已随本次更新一同发布。

上述两处修复的起因完全相同。某些检查虽然通过了,但通过的并不是真正关键的检查:测试套件全绿,但每个周期都丢失了一个小时;进程报告就绪,但它唯一依赖的关键资源已经耗尽。让测试保持绿色很容易。更难的问题在于,你的监控指标究竟需要捕获到什么异常才会亮起红灯,以及它们究竟能否捕获到这些异常。