Skip to content

fix(web): bind dashboard up front + fallback port; never falsely report live (#115) - #158

Merged
micahstubbs merged 1 commit into
mainfrom
claude/issue-115-dashboard-bind
Jun 7, 2026
Merged

fix(web): bind dashboard up front + fallback port; never falsely report live (#115)#158
micahstubbs merged 1 commit into
mainfrom
claude/issue-115-dashboard-bind

Conversation

@micahstubbs

Copy link
Copy Markdown
Owner

Closes #115.

sia run could announce Live dashboard: http://host:8000 even when the bind failed (the background thread discarded serve(...)'s result). Now the listener is bound synchronously up front and the printed URL reflects the actual bound port.

  • src/web/server.rs: serve_in_background(host, port, runs_dir, explicit_port) -> SiaResult<BackgroundDashboard{port, handle}> binds a TcpListener before spawning the server thread and hands it over (serve_with_listener). serve (foreground sia web) also binds up front (behavior unchanged). New bind_dashboard_listener: explicit --web-port → bind exactly that, actionable error on failure; default → try requested, then ~20 neighbors, then :0 (OS-assigned).
  • src/run.rs: detects an explicit --web-port (clap ValueSource::CommandLine); prints the dashboard URL only after a successful bind with the real port; returns the error for an explicit busy port; warns (without aborting the run) only if all default fallbacks fail. No new flag; --web-port semantics preserved.
  • tests/web_bind.rs (new): occupies a port and asserts explicit-busy errs, default-busy falls back to a different actually-bound port, and a free explicit port reports that exact port.

Gate green: fmt/clippy/test (default + --features llm) + scripts/parity_check.py → PARITY OK.

https://claude.ai/code/session_01WX3ZN9azxr1fyWuZAaRJ7Y


Generated by Claude Code

`sia run` auto-started the web dashboard via `serve_in_background`, which
spawned a thread, discarded the result of `serve(...)`, and printed
`Live dashboard: http://host:port` regardless of whether the bind
succeeded. A busy port (e.g. 8000) produced a URL where nothing served.

Now the listener is bound synchronously up front so bind failure is
observable on the calling thread:

- `serve_in_background` binds a `std::net::TcpListener` before spawning,
  hands the bound listener to the server thread (new `serve_with_listener`),
  and returns a `BackgroundDashboard { port, handle }` carrying the port
  that was actually bound. `serve` (foreground `sia web`) also binds up
  front; behavior is otherwise unchanged.
- New `explicit_port` parameter: when the user explicitly passed
  `--web-port`, a bind failure is returned as an actionable error. With
  the default port, `bind_dashboard_listener` tries the requested port,
  then a few incrementing neighbours, then an OS-assigned ephemeral
  port (`:0`).
- `run_orchestrator` detects an explicit `--web-port` via clap
  `ValueSource::CommandLine`, prints the real bound URL only after a
  successful bind, errors out for an explicit busy port, and warns
  (without aborting the run) only if every default fallback fails.

Adds `tests/web_bind.rs`: occupies an ephemeral port and asserts the
auto-start path does not falsely report a live dashboard — explicit port
errs, default port falls back to a different, actually-bound port.

https://claude.ai/code/session_01WX3ZN9azxr1fyWuZAaRJ7Y
@micahstubbs
micahstubbs merged commit df1dd75 into main Jun 7, 2026
15 checks passed
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.

Fail visibly or choose a fallback port when auto-starting the dashboard

1 participant