[harness] fix: 修复 AgentScheduler cancel 失效与 worker 取消挂起/泄漏#38
Merged
Conversation
- cancel() 引入 TicketState 状态机 + _tickets 登记表,仅对 queued 态 生效并唤醒调用方;删除恒返回 False 的 _cancel_in_queue - _drain_queue try/finally 保证 event.set()/active-=1/_tickets.pop 在 CancelledError(BaseException) 穿透时必达,调用方不再永久挂起、active 不泄漏 - 提取 app/agent/errors.py 解耦 scheduler 对 langgraph 的模块级依赖 (原 handlers.py 路径会拉起 memory/__init__ -> langgraph), handlers.py 改为 re-export,scheduler 错误路径也不再依赖 langgraph - TicketState(str, Enum) 替代魔法字符串;补 QueueFull/_schedule_one 提前 返回的 _tickets 泄漏修复;worker 取消设哨兵返回值;多 worker semaphore recheck cancelled;shutdown 清理 _tickets;cancel 原子性注释 - 新增 test_agent_scheduler.py(11 测试:cancel 5 + worker 取消 1 + state 契约 1 + retry 4);解耦后 test_agent_runtime.py(14) 恢复可跑
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
AgentScheduler存在两个 HIGH 级 bug,且整个模块零测试、生产中从未启用(bypass_scheduler=True默认旁路):_cancel_in_queue()恒返回False,ticket.cancelled全代码库无写入点 -> 对排队/延迟任务的取消完全不生效。_drain_queue在async with semaphore内 await_execute_with_retry,但后者只except Exception;asyncio.CancelledError(BaseException)穿透后跳过event.set()与slot.active -= 1-> 调用方永久挂起、active 计数泄漏。改动
TicketState状态机(queued/running/done/cancelled)+_tickets登记表;cancel()仅对queued态置cancelled=True并event.set()唤醒调用方;running/done 返回 False。删除_cancel_in_queue。event.set()/active-=1/_tickets.pop()在 CancelledError 穿透时必达;worker 取消设哨兵{"error":"worker cancelled"}区分空成功。app/agent/errors.py(ErrorCategory+classify_error,无 langgraph 依赖),handlers.py改为 re-export,scheduler 模块级直接导入。原from app.agent.memory.handlers会拉起memory/__init__->graph-> langgraph,使 scheduler 无法独立单测。TicketState(str, Enum)替代魔法字符串;QueueFull /_schedule_one提前返回补_tickets.pop();多 worker semaphore 等待期间被 cancel 的竞态 recheck;shutdown()清_tickets;cancel()原子性注释。test_agent_scheduler.py(11 测试:cancel 5 + worker 取消 1 + state 契约 1 + retry 4)。解耦后test_agent_runtime.py(14)恢复可跑(此前被 langgraph 阻塞)。验证
pytest app/test/test_agent_scheduler.py app/test/test_agent_runtime.py-> 25 passedruff check-> All checks passedpy_compile-> 通过sys.modules验证)影响范围
bypass_scheduler=True默认旁路,本次为潜伏 bug 清除 + 测试补全,不改变生产行为。app/agent/errors.py提取是纯重构,handlers.pyre-export 保持from app.agent.memory.handlers import classify_error不破。