feat(cli): hint at a foreground server when 'server down' has no pid file#146
Merged
Conversation
…file `ccas server status` HTTP-probes /health, so it reports *any* server up — including a foreground `ccas server up`, which writes no pid file. `down` only consults the pid file, so against a foreground server it printed "no/stale pid file" and exited, reading as if status and down disagree. The three no-detached-pid branches now probe the port too and, when a server still answers, point the user at the likely foreground instance the pid file can't reach (Ctrl-C, or find-pid-and-kill — not a blind `kill $(lsof)`). Exit code stays 1: down stopped nothing it manages. Probe + port resolution are extracted to a shared HealthProbe used by both Status and Stop, so the "hint fires exactly when status says running" invariant is structural, not a copy-paste promise. Stop.run takes an injected liveServerPort seam so its unit tests exercise the pid-file branches with no network. Main applies the ccas.env overlay before down (port parity with status). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sootopolis
added a commit
that referenced
this pull request
Jul 4, 2026
…ePort The `server.port` resolution was the third copy after #146 gave Status and Stop a shared HealthProbe. Route Detach's detached-launch readiness probe through HealthProbe.resolvePort too, so the one config key lives in one place. Behaviour-identical: application.conf defaults `port = 8080`, so the key always resolves and resolvePort's 8080 fallback (which Detach's bare getInt lacked) can never actually differ. Drops the now unused ConfigFactory import. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sootopolis
added a commit
that referenced
this pull request
Jul 4, 2026
…ePort (#148) The `server.port` resolution was the third copy after #146 gave Status and Stop a shared HealthProbe. Route Detach's detached-launch readiness probe through HealthProbe.resolvePort too, so the one config key lives in one place. Behaviour-identical: application.conf defaults `port = 8080`, so the key always resolves and resolvePort's 8080 fallback (which Detach's bare getInt lacked) can never actually differ. Drops the now unused ConfigFactory import. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
ccas server downnow, when it finds no detached server to SIGTERM (no pid file / corrupt / stale-dead pid), probes the server port and — if a server still answers — prints a hint pointing at the likely foregroundccas server up(which writes no pid file, sodowncan't reach it via the pid file). Exit code stays 1.Why
ccas server statusHTTP-probes/health, so it reports any server up — including a foreground one.downonly consults the pid file. Against a foreground server,statussaid "running" whiledownsaid "no/stale pid file" and exited, reading as if the two disagree. The hint closes that gap.How
HealthProbe(port resolution +/healthprobe) shared byStatusandStop, so the "hint fires exactly whenstatussays running" invariant is structural, not copy-paste.Statusrefactored onto it (dropped its private probe/timeouts/port constant).Stop.runtakes an injectedliveServerPort: UIO[Option[Int]]seam; the publicrunsupplies the real probe, unit tests supply a fixedSome/None→ pid-file branches tested with no network.lsof -ti tcp:<port>), not a blindkill $(…).Mainapplies theccas.envoverlay beforedown(port parity withstatus).Testing
sbt test: 1000 passed, 0 failed (pre-push hook + local).TestServeLifecycleStop.run suite made hermetic (injected seam) + a positive hint-path test added.Fixes
No open issue — follow-up to the
server up/downrename (#145); surfaced when a foreground server ran whiledownwas invoked.🤖 Generated with Claude Code