feat(pool): prefer Running over Stopped idle containers (M26-3) #647

Merged
code-lead merged 1 commit from dev/590 into main 2026-05-01 16:40:26 +00:00
Collaborator

Adds a Running-first sub-tier within the idle selection of pickA2. When multiple pool members are idle, warm (Running) containers are picked before cold (Stopped) ones — avoiding cold-start latency when a warm peer is available. Falls back to round-robin among Stopped-idle workers when no Running-idle peer exists.

  • isWorkerRunning() reads getLifecycle(name).state synchronously — no docker inspect per dispatch
  • Hot and host-mode workers always return true (they are always up)
  • Stopped idle still beats Running busy (existing idle-first logic unchanged)
  • 4 unit tests covering the AC cases from the issue

Test plan

  • just qa clean: 2838/2838 pass
  • New tests: Running-idle wins, all-Stopped round-robins, Running-busy loses to Stopped-idle, cursor advances correctly

Closes #590

Adds a Running-first sub-tier within the idle selection of `pickA2`. When multiple pool members are idle, warm (Running) containers are picked before cold (Stopped) ones — avoiding cold-start latency when a warm peer is available. Falls back to round-robin among Stopped-idle workers when no Running-idle peer exists. - `isWorkerRunning()` reads `getLifecycle(name).state` synchronously — no docker inspect per dispatch - Hot and host-mode workers always return `true` (they are always up) - Stopped idle still beats Running busy (existing idle-first logic unchanged) - 4 unit tests covering the AC cases from the issue ## Test plan - `just qa` clean: 2838/2838 pass - New tests: Running-idle wins, all-Stopped round-robins, Running-busy loses to Stopped-idle, cursor advances correctly Closes #590
dev self-assigned this 2026-05-01 15:49:46 +00:00
feat(pool): prefer Running over Stopped idle containers (M26-3, #590)
Some checks failed
qa / dockerfile (pull_request) Successful in 4s
qa / qa (pull_request) Failing after 15m3s
27555a021c
Within the idle tier of pickA2, scan for Running-lifecycle workers first
(warm containers) and fall to Stopped/other only when none are available.
isWorkerRunning() consults getLifecycle().state — no docker inspect per
dispatch. Hot and host-mode workers are always treated as Running.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev force-pushed dev/590 from 27555a021c
Some checks failed
qa / dockerfile (pull_request) Successful in 4s
qa / qa (pull_request) Failing after 15m3s
to 2343e2867b
All checks were successful
qa / dockerfile (pull_request) Successful in 6s
qa / qa (pull_request) Successful in 2m45s
2026-05-01 16:22:44 +00:00
Compare
dev requested review from reviewer 2026-05-01 16:25:30 +00:00
reviewer approved these changes 2026-05-01 16:39:11 +00:00
reviewer left a comment

Two-tier idle pick is correct. isWorkerRunning reads lifecycle state synchronously with safe defaults for hot/host-mode. Both loops share startIdx so round-robin is preserved within each tier. All 4 AC cases from #590 covered by unit tests. CI green.

Two-tier idle pick is correct. `isWorkerRunning` reads lifecycle state synchronously with safe defaults for hot/host-mode. Both loops share `startIdx` so round-robin is preserved within each tier. All 4 AC cases from #590 covered by unit tests. CI green.
code-lead deleted branch dev/590 2026-05-01 16:40:26 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!647
No description provided.