Skip to content

Windows 下 task-forest stale lock 无法可靠自动清理,导致长程 Agent 流程被迫手动删除 lock #2

Description

@Ronifue

问题概述

我使用的是 OpenCode 配合 oh-my-openagent 执行任务

task_forest.py 使用 .agent-workbench/task-forest/lock 作为 repo-local 锁。并发文档中说明:如果持锁 PID 已不存在,CLI 应自动清理 stale lock。

但我在 Windows 下遇到过 lock 文件中的 PID 已不存在,后续所有 task-forest 命令仍然无法获得锁,因为我的全局提示词为了安全不允许模型自己使用命令行删除东西,只能我手动执行命令来清理:

Remove-Item -LiteralPath ".agent-workbench\task-forest\lock"

这会打断需要一直跑的长程 Agent 工作流。

复现/触发场景

一个比较容易触发的场景是:Agent 在同一个 workspace 下短时间内调用多个 task-forest 命令,例如:

task_forest.py show TF-0022 --json
task_forest.py show TF-0027 --json

task-forest 当前的设计是所有 canonical graph 读写都会拿同一个独占锁。正常情况下这没问题,多个命令应该只是串行等待。
但如果某个持锁进程异常退出、被中断、或 Windows 文件句柄释放/进程状态判断出现问题,就可能留下 stale lock。之后 CLI 没有自动回收这个 lock,而是持续报锁占用,于是 Agent 便会要求用户手动处理,长程任务被迫中断。

可能原因

当前 _pid_alive() 使用:

os.kill(pid, 0)

在 Windows 上这不是可靠的 PID 存活检测。若它对不存在的 PID 抛出普通 OSError,当前实现会返回 None,于是 stale 判断走到:

unknown_stale = pid_alive is None and age >= TASK_FOREST_STALE_LOCK_SECONDS

而默认 stale 时间是 6 小时,导致已死亡 PID 的 lock 不能在短暂宽限后自动清理。

建议(由 GPT 润色提供)

  1. Windows 下用 ctypes 调 OpenProcess + GetExitCodeProcess 判断 PID 是否存活;
  2. PID 不存在时返回 False,让 DEAD_PID_GRACE_SECONDS 逻辑生效;
  3. 可选增加 lock-statuslock-clean --stale-only
  4. 文档中补充:同一 workspace 下 task-forest 命令建议串行调用,多节点读取优先用 list --json 而不是并行多个 show。

并行调用确实会放大问题,但不应导致用户手动清 lock。根问题是 Windows 下 stale lock 自动恢复不可靠。

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