本地执行器重连后,别急着重派 Agent 任务:先做一次执行对账
本地执行器重连后,别急着重派 Agent 任务:先做一次执行对账
摘要:本地浏览器、文件或桌面动作在回执前断线时,超时并不等于失败。本文用执行凭证、资源版本和状态机,把“重连即重试”改成可审计的对账与恢复决策。
一个 Agent 在本地浏览器里点了“保存”,随后客户端网络断开。云端没有收到结果:这时任务是失败、成功,还是未知?
许多系统会把它粗暴地压缩为“超时”,然后在重连后重新派发。对读取操作,这通常只是浪费;对发布、提交、转账、写文件这类动作,却可能制造第二次副作用。
真正需要恢复的不是连接,而是事实:那次执行到底有没有发生、发生在哪个资源版本上、结果能否再次确认。
超时只说明观察失败
一次跨云端与本地的执行,至少有三个彼此独立的事件:
- 云端接受了派发请求;
- 本地执行器实际开始并完成了动作;
- 结果回执被云端持久化。
网络中断可能发生在任意两个事件之间。若第二步已经完成、第三步丢失,云端把它当成“未开始”并重派,就会把一次“保存”变成两次提交。
AWS 对可恢复执行的说明也指出:重放会再次运行中断的步骤,有副作用的步骤只有在幂等时才适合至少一次重试。来源
把未知态放进状态机
不要只使用 pending / success / failed 三态。对副作用动作,至少增加 dispatched、running、unknown 与 reconciled:
pending -> dispatched -> running -> succeeded
| |
v v
unknown ------> reconciled
|
+--> retryable / manual-review
unknown 不是失败的委婉说法,而是一条操作纪律:系统不知道动作是否发生,就不能把重试当默认选项。它应先触发一次只读对账。
执行凭证应该包含什么
一张可用的对账单不必很大,但要能稳定关联一次副作用:
| 字段 | 用途 |
|---|---|
operationId | 同一业务动作跨重连保持不变,作为幂等键 |
taskId + attempt | 区分业务任务和具体尝试 |
resourceKey | 指向页面、文件或设备等本地资源 |
preconditionVersion | 记录动作前看到的版本/哈希/表单状态 |
effectProbe | 一个只读检查:例如页面回执号、文件哈希或目标状态 |
receipt | 本地已完成的证据及可重传结果 |
关键取舍是:不要把“浏览器仍在打开”当作凭证。窗口活着不能证明点击生效;反过来,窗口关闭也不必然说明动作失败。证据必须落到业务效果或平台回执上。
重连后的四步恢复协议
第一步:认领原任务,不创建新任务。 用 operationId 找回原尝试,并保留它的资源 owner,避免两个执行器同时对账。
第二步:回传本地持久记录。 如果本地已保存成功结果,优先重传回执;这不是重新执行。
第三步:做只读 effect probe。 例如查询是否存在同一回执号、目标文件是否已是预期哈希、页面是否已经进入下一状态。
第四步:按证据分流。
| 对账结果 | 动作 |
|---|---|
| 效果存在且匹配 | 标记成功,补写回执 |
| 效果不存在且前置版本仍匹配 | 可在同一 operationId 下重试 |
| 效果存在但无法关联 | 进入人工复核,不做自动覆盖 |
| 前置版本已变化 | 停止重试,要求重新读取上下文 |
这与消息系统的经验一致:成功但未确认、连接短暂断开都可能导致重复投递,因此消费端仍须幂等,不能只依赖发送端去重。来源
为什么“幂等键”还不够
幂等键能防住同一目标系统的重复写入,却不能回答“这次写入是否仍符合当前上下文”。例如,一个表单的草稿在断线期间被人修改;重试旧操作即使不重复,也可能覆盖新的意图。
所以执行凭证还要带前置版本。幂等回答“做几次”;版本校验回答“现在还能不能做”。二者一起,才把重连后的自动化限制在可解释的范围内。
一条产品实现原则
在 Tipkay 这类把云端任务状态与本地工具执行结合的架构中,本地结果先持久化、网络恢复后再回传的价值,正是在这里体现:连接中断时保留的是执行事实,而不是一段等待重试的空白。
这不是“永不重试”的承诺。它要求系统在重试前先区分:已完成但未被看见、确实未执行、以及无法判断的未知态。对真实工作而言,能安全地停在未知态,往往比自信地再点一次更可靠。
结语
云端编排给任务分工,本地执行接触真实资源。两者之间最容易被忽略的,不是网络断开本身,而是断开后事实的归属。
把重连设计成一次执行对账:先找凭证、再查效果、最后决定是否重试。这样,系统恢复的就不只是连接,而是对这次副作用的控制权。
更多推荐

所有评论(0)