Skip to content

Comments

feat: dynamic sidecar port with EADDRINUSE fallback#375

Open
koala73 wants to merge 1 commit intomainfrom
feat/dynamic-sidecar-port
Open

feat: dynamic sidecar port with EADDRINUSE fallback#375
koala73 wants to merge 1 commit intomainfrom
feat/dynamic-sidecar-port

Conversation

@koala73
Copy link
Owner

@koala73 koala73 commented Feb 25, 2026

Summary

  • Rust probes port 46123 via TcpListener::bind; if busy, binds port 0 for OS-assigned ephemeral port
  • Actual port stored in LocalApiState, passed to sidecar via LOCAL_API_PORT env, exposed to frontend via get_local_api_port IPC command
  • Frontend resolves port lazily on first API call with retry-on-failure semantics, caches result
  • All hardcoded 46123 references replaced with dynamic getApiBaseUrl()/getLocalApiPort() accessors
  • CSP connect-src broadened to http://127.0.0.1:* (frame-src unchanged)

Motivation

When port 46123 is occupied (stale sidecar from previous crash, another app, or dev restart), the sidecar crashes silently with exit(1) and ALL panels show UNAVAILABLE. This particularly affects Windows where Node.js processes may linger after app close.

Files changed

File Change
src-tauri/src/main.rs Port probing, LocalApiState.port, get_local_api_port IPC, DesktopRuntimeInfo.local_api_port
src/services/runtime.ts resolveLocalApiPort(), getLocalApiPort(), dynamic getApiBaseUrl(), per-call URL in fetch patch
src/services/runtime-config.ts Sidecar URLs use getApiBaseUrl() instead of hardcoded constants
src/settings-main.ts Port primed via resolveLocalApiPort() at init, getSidecarBase() dynamic
src/components/LiveNewsPanel.ts Origin check uses getApiBaseUrl()
src/components/ServiceStatusPanel.ts Display port uses getLocalApiPort()
index.html + tauri.conf.json CSP connect-srchttp://127.0.0.1:*

Test plan

  • cargo check passes
  • npx tsc --noEmit passes
  • Normal launch: sidecar binds 46123, panels load
  • EADDRINUSE: hold port 46123 with node -e "require('net').createServer().listen(46123, '127.0.0.1')", launch app → sidecar binds alternate port → panels load
  • Check desktop.log for local API sidecar using port <N>
  • Settings window diagnostics (Debug tab) connect to correct port
  • Secret verification in settings works on non-default port

Rust probes port 46123 via TcpListener::bind; if busy, binds port 0 for
an OS-assigned ephemeral port. The actual port is stored in LocalApiState,
passed to sidecar via LOCAL_API_PORT env, and exposed to frontend via
get_local_api_port IPC command.

Frontend resolves the port lazily on first API call (with retry-on-failure
semantics) and caches it. All hardcoded 46123 references replaced with
dynamic getApiBaseUrl()/getLocalApiPort() accessors. CSP connect-src
broadened to http://127.0.0.1:* (frame-src unchanged).
@vercel
Copy link

vercel bot commented Feb 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Feb 25, 2026 0:55am
worldmonitor-finance Ready Ready Preview, Comment Feb 25, 2026 0:55am
worldmonitor-happy Ready Ready Preview, Comment Feb 25, 2026 0:55am
worldmonitor-startup Ready Ready Preview, Comment Feb 25, 2026 0:55am

Request Review

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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