Skip to content

feat(status): bounded --wait-daemon-running for SessionStart loops (#284.2)#300

Merged
laulpogan merged 1 commit into
mainfrom
fix/284-2-bounded-sessionstart-wait-loop
Jun 15, 2026
Merged

feat(status): bounded --wait-daemon-running for SessionStart loops (#284.2)#300
laulpogan merged 1 commit into
mainfrom
fix/284-2-bounded-sessionstart-wait-loop

Conversation

@laulpogan

Copy link
Copy Markdown
Collaborator

Part 2 of #284 (Willard's Windows report).

Summary

Willard's SessionStart bringup ran a bash loop:

```
until wire status 2>/dev/null | grep -q 'daemon_running":true'; do
sleep 3
done
```

With a never-healthy daemon (because #284.1's wedged probes kept `wire status` from ever returning `daemon_running:true`), the loop ran forever, spawning a fresh hanging `wire status` every 3 seconds. Over many sessions/days it piled up 254 `wire.exe` processes, each wedged on a PowerShell `Get-CimInstance` probe.

#284.1 fixes the probe so even an external `until` loop now terminates. This PR additionally removes the need for the external loop entirely: ship a bounded in-process primitive.

New flag

`wire status --wait-daemon-running [--timeout ]`

  • Polls the daemon-liveness snapshot every 200ms in-process — no re-spawn pressure, no PowerShell-per-cycle cost, no orphan accumulation.
  • Default `--timeout 30`, overridable.
  • Healthy path: print the full status surface (identical to `wire status` JSON / human output), exit 0.
  • Timeout path: emit the last-seen `pidfile_pid` and `pgrep_pids` on stderr (so the operator can see what state was lingering), exit non-zero so shell wrappers can branch.

Pure-logic

`WaitDecision` + `wait_step(pidfile_alive, now, deadline) -> WaitDecision` is the policy core. It's a 3-way decision: `Healthy` if the daemon is up, `TimedOut` if the deadline elapsed and it isn't, `Continue` if there's still budget. Extracted so the policy is unit-testable without a real daemon.

Tests

4 new pure-logic `wait_step_*`, all green on `x86_64-pc-windows-msvc` (rustc 1.96.0):

  • `wait_step_returns_healthy_when_pidfile_alive`
  • `wait_step_returns_timed_out_when_deadline_passed_and_dead`
  • `wait_step_returns_continue_when_deadline_future_and_dead`
  • `wait_step_healthy_wins_over_timeout` — locks down the "deadline elapsed AND daemon just came alive on the same tick" race: success wins, we don't punish the operator for missing by a millisecond.

Full lib suite: 490 passed; 0 failed; 7 ignored.

Recommended SessionStart usage

Replace this:

```bash
until wire status 2>/dev/null | grep -q 'daemon_running":true'; do
sleep 3
done
```

with this:

```bash
wire status --wait-daemon-running --timeout 30 --json >/dev/null
|| { echo "wire daemon never came up"; exit 1; }
```

One spawn instead of unbounded N. Bounded wall-clock. Clear exit codes.

Stack

Stacks on top of #294 (Windows test/clippy hygiene). Sibling Windows-cluster PRs already open: #296 (#284.5), #297 (#247.4), #298 (#284.1). #284.2 pairs naturally with #284.1: combined, the external `until` loop terminates cleanly AND has a built-in replacement that doesn't churn at all.

Test plan

  • `cargo fmt --check` clean on Windows.
  • `cargo clippy --all-targets -- -D warnings` clean on Windows.
  • `cargo test --lib` 490/0/7 on Windows.
  • CI green.
  • Manual repro: run `wire status --wait-daemon-running --timeout 5` with no daemon, confirm it bails after 5s with the `pidfile_pid` / `pgrep_pids` line on stderr. Run with a healthy daemon, confirm it prints the full status and exits 0.

🤖 Generated with Claude Code

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploying wireup-landing with  Cloudflare Pages  Cloudflare Pages

Latest commit: 397000c
Status: ✅  Deploy successful!
Preview URL: https://9ee1c63d.wireup-landing.pages.dev
Branch Preview URL: https://fix-284-2-bounded-sessionsta.wireup-landing.pages.dev

View logs

@laulpogan laulpogan force-pushed the fix/284-2-bounded-sessionstart-wait-loop branch 4 times, most recently from 06f78b1 to 69eecfe Compare June 15, 2026 02:01
…284.2)

Issue #284 part 2 (from Willard's Windows report). The
SessionStart bringup ran a bash loop:

    until wire status 2>/dev/null | grep -q 'daemon_running":true'; do
        sleep 3
    done

With a never-healthy daemon (because #284.1's wedged probes kept
`wire status` from ever returning `daemon_running:true`) the loop ran
forever, spawning a fresh hanging `wire status` every 3 seconds. Over
many sessions/days it piled up 254 `wire.exe` processes, each wedged
on a PowerShell `Get-CimInstance` probe. #284.1 fixes the probe; this
fix removes the need for the external loop entirely by giving
operators a single bounded in-process primitive.

New flag: `wire status --wait-daemon-running [--timeout <secs>]`.

  - Polls the daemon-liveness snapshot every 200ms IN-PROCESS — no
    re-spawn pressure, no PowerShell-per-cycle cost.
  - Default `--timeout 30`, overridable per invocation.
  - Healthy path: print the full status surface (same JSON / human
    output `wire status` produces), exit 0.
  - Timeout path: emit the last-seen `pidfile_pid` and `pgrep_pids`
    on stderr (so the operator can see what state was lingering),
    return a non-zero `anyhow::Error` so shell wrappers can branch.

Pure-logic `WaitDecision` + `wait_step(pidfile_alive, now, deadline)`
extracted so the policy is unit-testable without a real daemon.
Tests lock down the three branches plus the "deadline elapsed AND
daemon just came alive on the same tick → success wins" case (we
don't punish the operator for the missed-by-a-millisecond race).

Tests: 4 new pure-logic `wait_step_*`. Full lib suite: 490 passed;
0 failed; 7 ignored on `x86_64-pc-windows-msvc` (rustc 1.96.0).

if the operator keeps using it (because status returns fast now),
AND there's a built-in alternative that avoids the spawn churn
entirely.

Stacks on top of #294 (Windows test/clippy hygiene); rebase onto main
once #294 lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: laul.pogan <paul@zaibatsuheavy.industries>
@laulpogan laulpogan force-pushed the fix/284-2-bounded-sessionstart-wait-loop branch from 69eecfe to 397000c Compare June 15, 2026 02:07
@laulpogan laulpogan merged commit 50f5adc into main Jun 15, 2026
12 checks passed
@laulpogan laulpogan deleted the fix/284-2-bounded-sessionstart-wait-loop branch June 15, 2026 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant