长程任务的实现核心挑战在于异步回调和故障恢复。它们可能运行几十秒甚至几分钟。请求提交后,原始节点不一定一直存活,回调也不一定返回原节点,还可能出现:

Claw任务提交后只返回ACK,最终结果通过MQ或HTTP回调回来,系统通过运行时上下文和RedisList 、 Pub、Sub跨节点关联。,通过双层心跳、分布式锁和乐观锁恢复。

Agent run

Agent运行时状态以session维度以Agent_run的形式持久化到MySQL Checkpoint中。主要信息包括:session_id(当前请求id)、 trace_id(全链路id,由于全链路可能涉及到多次Agent调用,一个trace_id 可能对应多个sessionID)、current_iter(重试时的当前轮次)、task_id、task_instance_Id 对于周期性定时任务,还需要存储本次任务的单次实际执行id、以及业务专属的utdid、channel id、extra_data等。

运行状态中,各个Agent和Tool执行的中间结果,都由以上的id进行串联。

这些信息,主要起到三个作用:

  • 恢复上下文:实际执行模块挂了可以单模块恢复。
  • 重建原始请求:整个请求都失败了,可以直接重建请求
  • 异步回调:系统在等待异步回调时先释放在线线程。

乐观锁

在数据表中增加一个 version 字段。

  • 读取时:查出当前数据及其版本号(例如 version = 1)。
  • 更新时:在 SQL 的 WHERE 条件中带上这个版本号。
UPDATE user_table 
SET name = 'new_name', version = version + 1 
WHERE id = 1 AND version = 1;

如果此时其他线程已经把 version 改成了 2,这条 SQL 就会影响 0 行,从而知道更新失败。