Skip to content

[缺陷]: 服务重启后 stale running 任务会被自动续跑,重复触发上游请求 #10

@AK-103U

Description

@AK-103U

影响区域

运行时 / worker / queue

部署方式

本地 npm run dev / start

Provider 模式

与 provider 无关

使用的模型别名

任意

Base URL 形态

任意

复现步骤

  1. 启动服务并创建一个 auto 运行的任务,让它进入 running 状态。
  2. 在该任务某一轮尚未自然收口时,直接停止服务进程或关闭容器,不做任务级暂停。
  3. 重新拉起服务。
  4. 打开任务列表页或任务详情页;这些 API 请求会顺手启动 worker。
  5. 观察该任务会再次被 claim,并继续执行。
  6. 如果重复执行“停止服务 -> 拉起服务 -> 打开页面/触发 API”,该任务会继续被重新接管并继续跑。

预期行为

服务重启后,不应该无条件继续消费此前的 running 任务,至少不应该无限次自动恢复。

更符合预期的语义建议是以下任一类:

  • 只自动恢复 pending 任务;对 stale running 任务转为 pausedmanual_review
  • 或者允许自动恢复,但需要有明确的恢复次数上限、退避策略,以及可见的恢复原因。
  • 至少应避免“只要服务反复拉起,任务就继续打上游请求”的无限恢复行为。

实际行为

当前实现会把心跳超时的 running 任务视为可继续 claim 的任务;服务重新拉起且 worker 被启动后,这类任务会被再次接管并继续执行。

这会带来几个问题:

  • 进程异常退出或人工停服务后,操作者很难把“停服务”解释为“先别继续跑”。
  • 即使数据库提交有 claim 防护,仍可能重复触发上游 provider 请求,造成额外 token / 时间 / 并发消耗。
  • 如果环境处于反复重启、容器漂移或上游持续异常的状态,任务会被不断重新拉起继续撞,没有明显的自动恢复上限或熔断。

日志、截图或补充信息

我本地检查实现时看到的相关行为如下:

  • claimNextRunnableJobRow() 会把 pending,以及心跳超过 30 秒的 running 任务都视为可 claim。
  • ensureWorkerStarted() 会在任务列表 / 任务详情等 API 被访问时启动 worker。
  • 当前没有看到显式的优雅停机 / shutdown 收口逻辑,因此这更像“靠 stale claim 自动接管”,而不是一个有边界的重启恢复策略。

如果项目当前就是想保留“自动恢复”语义,我建议至少补充:

  • running stale task 的自动恢复次数限制
  • 恢复原因与次数的可观测字段 / UI 暴露
  • 明确区分“用户手动 resume”与“进程重启后自动接管”

提交前确认

  • 我已经移除了 API Key、Token 和其他敏感信息。
  • 我已经先查看了 README 和部署文档里的预期行为。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions