Add standalone symphony-server bin for out-of-process operation - #10
Conversation
Ships a config-file-driven Node entrypoint (the `symphony-server` bin) that runs symphony as its own OS process. It reads a JSON config of per-port proxies, resolves private keys referenced by file path, hot-reloads routes when the config file changes, writes a status.json (pid + version) for supervisors, and stops gracefully on SIGTERM/SIGINT (SIGHUP reloads). Reuses the existing napi SymphonyProxy API unchanged; the file-path cert form is resolved only in the server layer so CertConfig stays inline-only. Bumps to 0.4.0. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The status file is rewritten on every config reload; a supervisor polling it concurrently could read a half-written document and treat symphony as down. Write via temp + rename so reads always see a complete file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a standalone server binary (symphony-server) that runs the symphony proxy as an independent OS process, featuring dynamic configuration hot-reloading, status file writing, and graceful signal handling. It also adds comprehensive integration tests and updates package configurations and documentation. The review feedback highlights critical safety improvements, specifically addressing unsafe non-null assertions on optional certificate configuration fields that could cause runtime errors, and recommending that the file watcher instance be stored, error-handled, and closed properly on shutdown to prevent resource leaks.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Heads-up for reviewers: the Harper UDS proxy integration check is red, but it's a pre-existing CI infrastructure failure unrelated to this PR — it fails on `main` and every recent run because that job builds `harper-pro` without checking out its `core` submodule (`error TS2307: Cannot find module '../core/...'`). All platform builds and the unit-test jobs (including the new `server.spec.ts`) pass. No code in this PR touches that path. — Claude (Opus), on behalf of Kris (AI-generated) |
- resolveCert/resolveMtls: drop the unsafe non-null assertions; throw a descriptive error when neither the inline value nor a file path is provided (previously a missing field produced a cryptic path TypeError). - ServerState: keep the FSWatcher on the instance, register an 'error' listener (an fs.watch error would otherwise throw unhandled), and close it in stop(). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Adds a
symphony-serverbin (ts/server.ts→dist/server.js) that runs symphony as its own OS process, driven by a JSON config file it watches and hot-reloads. No Rust changes — it reuses the existing napiSymphonyProxyAPI. Bumps to0.4.0.Why
host-manager currently loads symphony in-process, so restarting host-manager takes the edge proxy down with it. This bin lets a supervisor (host-manager — see the paired PR in HarperFast/host-manager) run symphony as a separate, independently-restartable process, and makes the live proxy configuration a readable file.
What it does
{ version, proxies: [{ listeners, routes }] }— one proxy entry per port-set (the route table is per-proxy). Cert chains are inline PEM; private keys may be referenced byprivateKeyFilepath, resolved only in the server layer so the napiCertConfigstays inline-only.updateConfig, a listener change → recreate that proxy.status.json({ pid, version, ports, ... }, atomic temp+rename) for supervisors;SIGHUPreloads,SIGTERM/SIGINTstop gracefully.Where to look
ts/server.ts— the whole bin. Worth a careful read:resolveCert(the file-path cert handling) and the reconcile/portKeymatching that decides hot-swap vs. recreate.__test__/server.spec.ts— spawns the real bin and asserts status/version, TLS served with a key loaded by path, and live route reload.Notes