mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-10 17:57:54 -10:00
Surfaced by a full-tree audit; each ships a regression test where the behavior is deterministically testable. - swarm: deliver a handoff's mailbox note BEFORE registering the new task, so a mailbox failure can't leave a phantom pending task in the coordinator. - specialist: put a foreground sub-agent child in its own process group and group-kill on cancel/timeout (+ WaitDelay backstop), so a build/server it forked dies with it instead of orphaning. - oauth: serialize on-demand token refresh per key (keyed mutex) and re-load inside the lock, so parallel callers don't each spend the single-use refresh token (all but one would otherwise fail at the token endpoint). - mcp: treat a "source already gone" rename during legacy-token migration as success, so a concurrent migrator doesn't wrongly drop an OAuth MCP server. - cron: claim a due job atomically (advance NextRunAt under the per-job lock) before running it, so two schedulers can't double-fire the same job.
41 lines
1.3 KiB
Go
41 lines
1.3 KiB
Go
//go:build !windows
|
|
|
|
package specialist
|
|
|
|
import (
|
|
"errors"
|
|
"os/exec"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// specialistWaitDelay bounds how long Wait blocks for the child's stdout pipe to
|
|
// drain after the process exits or its context is cancelled, so a leaked
|
|
// grandchild holding the pipe cannot hang the parent past cancel/timeout. Var
|
|
// (not const) so tests can shorten it.
|
|
var specialistWaitDelay = 2 * time.Second
|
|
|
|
// hardenSpecialistChild makes a foreground specialist child killable as a single
|
|
// unit. Setpgid puts the child into its own process group, so on cancel/timeout
|
|
// we signal the whole group (negative pid) — any build/server/bash the sub-agent
|
|
// forked dies with it instead of being orphaned. WaitDelay is the backstop if a
|
|
// grandchild still holds the stdout pipe after the group is killed. Must be
|
|
// called before command.Start (M6).
|
|
func hardenSpecialistChild(command *exec.Cmd) {
|
|
if command.SysProcAttr == nil {
|
|
command.SysProcAttr = &syscall.SysProcAttr{}
|
|
}
|
|
command.SysProcAttr.Setpgid = true
|
|
command.WaitDelay = specialistWaitDelay
|
|
command.Cancel = func() error {
|
|
if command.Process == nil {
|
|
return nil
|
|
}
|
|
// Negative pid targets the whole process group led by the child.
|
|
if err := syscall.Kill(-command.Process.Pid, syscall.SIGKILL); err != nil && !errors.Is(err, syscall.ESRCH) {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
}
|