fix: derive active count from activeTaskIds.size, constrain ps scan

Address two additional review concerns:

1. Remove separate 'active' counter from LaneState; derive it from
   activeTaskIds.size instead. This makes negative-underflow impossible
   — the Set is the single source of truth for active task count.
   Previously, a double-reset scenario could drive 'active' negative,
   violating the concurrency check in pump().

2. Replace unbounded 'ps -axo pid=,command=' with targeted pgrep
   pre-filter in orphan scanner. Only fetches full command info for
   candidate PIDs matching 'codex|claude', avoiding O(all-processes)
   overhead on large hosts.
This commit is contained in:
Joey Krug
2026-02-13 05:02:47 +00:00
committed by Gustavo Madeira Santana
parent 8eb80b6d0b
commit b8190d35aa
2 changed files with 21 additions and 16 deletions

View File

@@ -59,8 +59,21 @@ function resolveCwd(pid) {
return match ? match[1] : "unknown";
}
const lines = run("ps -axo pid=,command=").split("\n");
const includePatterns = [/\bcodex\b/i, /\bclaude\b/i, /claude\s+code/i];
// Pre-filter candidate PIDs using pgrep to avoid scanning all processes.
// Falls back to full ps scan if pgrep is unavailable.
const candidatePids = run("pgrep -f 'codex|claude' 2>/dev/null || true")
.split("\n")
.map((s) => s.trim())
.filter((s) => s.length > 0 && /^\d+$/.test(s));
let lines;
if (candidatePids.length > 0) {
// Fetch command info only for candidate PIDs.
lines = run(`ps -o pid=,command= -p ${candidatePids.join(",")}`).split("\n");
} else {
lines = [];
}
const excludePatterns = [
/openclaw-gateway/i,
/signal-cli/i,
@@ -85,9 +98,6 @@ for (const rawLine of lines) {
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) {
continue;
}
if (!includePatterns.some((pattern) => pattern.test(cmd))) {
continue;
}
if (excludePatterns.some((pattern) => pattern.test(cmd))) {
continue;
}