返回博客

Reliability · 2026年7月1日

实时翻译更新应该是有用的,而不是必需的

实时状态很有价值,但当实时基础设施不可用或被有意禁用时,翻译操作仍应保持正确。

实时翻译更新应该是有用的,而不是必需的

看着一次翻译从排队到处理中再到就绪,这很有用。团队无需刷新就能看到进度,能快速打开已完成的工作,也能在发布仍在进行时注意到失败的请求。

但实时更新是一种展示能力。它不应成为让工作流保持正确的机制。

持久状态优先

数据库和任务系统应该掌管翻译状态。无论浏览器是否连接,每一次阶段转换都需要被记录:

  • 请求已排队
  • 翻译已开始并完成
  • 推送已开始并完成
  • 发布已开始并完成
  • 失败和重试事件

实时事件可以用来宣布这种持久化变更,但不应成为该变更发生的唯一记录。

这种区分能保护那些关闭标签页、失去网络连接,或在 websocket 基础设施被禁用的环境中工作的用户。

实时能力有运营成本

广播会引入更多活动部件:websocket 服务、连接授权、频道配置、代理支持,以及浏览器重连行为。

对于需要实时协作的团队,这种成本可能是值得的。对于较小规模的部署,普通轮询可能更简单,而且完全足够。

让实时功能成为可选项,能让每个环境选择自己能够支持的运营模式,同时不失去核心翻译行为。

设计优雅的回退方案

无论通过实时事件还是周期性刷新,UI 都应该到达相同的最终状态。

一种实用的方法是:

  1. 加载当前的持久状态
  2. 在启用实时功能时订阅相关事件
  3. 按请求 ID 和版本合并传入的更新
  4. 只要仍有活动中的工作,就以适中的间隔轮询
  5. 当批次到达终态时,停止高频轮询

实时更新让界面感觉更及时。轮询可以在重连后补上空档,并提供回退方案。

这两条路径不应形成相互竞争的状态规则。

避免让更新变成噪音

并不是每个内部事件都适合出现在界面里。广播每一个 token、worker 心跳或中间保存,可能会让页面变得不稳定,并增加基础设施负载。

用户通常需要的是有意义的阶段转换和更新后的计数。把快速发生的底层变更归并为更少的一组持久里程碑,能让体验保持平稳且易于浏览。

同样的原则也适用于通知。一个已完成的批次可能值得提醒,但每个已完成的 locale 很可能并不需要。

测试安静路径

人们很容易在启用实时功能时进行测试,并假设回退机制也能正常工作。可靠性要求进行相反的练习:

  • 禁用广播
  • 启动一个多 locale 批次
  • 离开页面后再返回
  • 确认进度能够补齐
  • 重试失败的请求
  • 验证最终计数和可用操作

如果这条路径可行,那么实时功能就是增强,而不是隐藏的依赖。

要点

当实时更新建立在持久状态之上时,它们会改善翻译操作。

先记录每一次状态转换,让广播可配置,并保留一种克制的轮询回退机制。即使最即时的传递通道不可用,工作流也应该保持可信。