MUL-4976: feat(daemon): add drain-aware restart for active tasks#5631
MUL-4976: feat(daemon): add drain-aware restart for active tasks#5631wjueyao wants to merge 4 commits into
Conversation
|
@wjueyao is attempting to deploy a commit to the IndexLabs Team on Vercel. A member of the Team first needs to authorize it. |
multica-eve
left a comment
There was a problem hiding this comment.
此前,管理员在已有工作进行时更新本机运行程序,只能立即打断这些工作;改动后,管理员可以选择先停止接收新工作,等已开始的工作自然结束后再更新。原来的立即更新方式保持不变。
✅ 产品上应该接受。 这个可选能力能避免维护操作制造失败尝试、重复执行和额外模型消耗。
🔄 请求修改:等待期间仍可能被服务端下发的更新打断。
server/internal/daemon/daemon.go:2699 的 drain barrier 只与周期性 auto-update 协调;心跳触发的 handleUpdate(:2529)不检查或持有该 barrier,并在 :2574 直接调用 triggerRestart()。因此两个并发顺序都会破坏本功能的核心保证:
- drain 已开始后收到 pending update,会取消仍在运行的任务;
- pending update 先开始时,drain 仍会成功进入,随后被更新重启打断。
请将手动 drain、周期性 auto-update、心跳触发 update 纳入同一个带 owner 的互斥协议:drain 持有时 update 应延后;update 已开始时 drain 应返回冲突。请补齐 drain → update 和 update → drain 两个顺序的并发测试,证明任何一方都不能绕过另一方的所有权。
Use one owner-checked claim barrier for manual drain, periodic auto-update, and heartbeat-triggered update. Cover both concurrency orderings with deterministic regression tests.
|
Addressed the drain/update concurrency gap in
Local verification: The new CI run is in progress. |
What does this PR do?
Adds an opt-in
multica daemon restart --drainmode that stops claiming new tasks, lets accepted agent work finish naturally, and only then restarts the daemon.Thinking path
/shutdownpath cancels the daemon root context, which is also passed to active agent tasks. The subsequent 30-second wait is cleanup after cancellation, not a real drain.runtime_recoveryis an important crash fallback, but it still records a failed attempt, redispatches work, and can spend more model tokens resuming it. It should not be the normal restart protocol.active_task_count > 0; explicit CLI restarts lacked the equivalent capability.claimsInFlightandactiveTasksto reach zero. The batch poller incrementsactiveTasksbefore releasingclaimsInFlight, so there is no false-idle window during claim handoff./shutdown/drainendpoint. A new CLI talking to an older daemon therefore gets a safe 404 instead of having an old/shutdownhandler ignore a query parameter and stop immediately.Plain
multica daemon restartremains unchanged for backwards compatibility.Related Issue
Closes #5630
Related context: #1041; orthogonal to the cross-profile ownership work in #5494.
Type of Change
Changes Made
daemon restart --drainCLI flag and a caller-cancellable, unbounded local request suitable for long-running agent tasks.drainingin local health output.How to Test
Automated verification run locally on macOS arm64 with Go 1.26.1:
All commands above pass;
gofmt -lproduces no output.Manual reviewer flow:
multica daemon restart --drainin another terminal.draining: true, no new task is claimed, and the active task completes without aruntime_recoveryfailure.Risks and compatibility
409rather than changing barrier ownership./shutdown/drain; they fail safely with404and are left running.Checklist
AI Disclosure
AI tool used: OpenAI Codex
Prompt / approach: Reproduced the daemon lifecycle semantics from
main, compared the existing Desktop deferred-restart and auto-update claim-barrier designs, reviewed adjacent PR #5494 for overlap, then implemented test-first. The final diff received separate race/behavior, compatibility/scope, and PR-readability reviews before publication.