Skip to content

server: validate the backend before binding the port - #399

Closed
CryptVenture wants to merge 1 commit into
0xShug0:mainfrom
CryptVenture:pr/server-backend-probe
Closed

server: validate the backend before binding the port#399
CryptVenture wants to merge 1 commit into
0xShug0:mainfrom
CryptVenture:pr/server-backend-probe

Conversation

@CryptVenture

@CryptVenture CryptVenture commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Split out of #369 as requested: this PR is only the startup backend probe. The language contract gate, the ASR detail fields and the unload locking are separate PRs.

The problem

--backend defaults to cuda and nothing verified it at startup. On a host where that backend is not registered the server still bound its port and served the whole UI — health, model list, downloads — with an engine that could not run anything:

$ audiocpp_server --ui --backend cuda --port 8096
$ curl localhost:8096/health
{"status":"ok","backend":"cuda","models":0,"ui":true,"ui_management":false}

/health reports ok on an Apple-silicon machine with no CUDA device. The operator only finds out at the first model load or generate, by which time the failure looks like a model problem rather than a startup flag.

The change

main() initialises the requested backend and device once before constructing the server, then frees it. A missing backend or device now aborts startup with the message the engine would have raised later:

$ audiocpp_server --ui --backend cuda --port 8096
audiocpp_server failed: CUDA backend requested but it is not registered in this build
(available: MTL:0 "Apple M4 Max" [GPU], BLAS:0 "Accelerate" [ACCEL], CPU:0 "Apple M4 Max" [CPU])

The message already names the devices that are available, so the operator can correct --backend/--device immediately. The probe runs on a path that loads the backend libraries anyway and does not touch the request path.

Validation

Backend: Metal, Apple M4 Max, macOS 15.

Command main this branch
--ui --backend cuda binds, /health{"status":"ok","backend":"cuda"} exits, CUDA backend requested but it is not registered in this build
--ui --backend metal binds, /health{"status":"ok","backend":"metal"} binds, /health{"status":"ok","backend":"metal"}

Build and tests:

cmake --build build/macos-metal-tests -j 12
ctest --test-dir build/macos-metal-tests        # 40/40

Scope

One file, app/server/main.cpp, 15 added lines. Startup only; no request, model or response behaviour changes.

The server backend defaults to CUDA and nothing verified it at startup, so on a
machine where that backend is not registered the process bound its port and
served the whole UI — health, model list, downloads — with an engine that
could never run anything. /health answered {"status":"ok","backend":"cuda"} on
an Apple-silicon host with no CUDA device, and the operator only learned the
truth when the first model load or generate failed.

main() now initialises the requested backend and device once, before
constructing the server, and frees it again. A missing backend or device
therefore aborts startup with the same message the engine would have raised
later, at the point the operator can still change --backend or --device.

The probe costs one backend init on a path that already loads Metal or CUDA
libraries and does not touch the request path.
@CryptVenture

Copy link
Copy Markdown
Contributor Author

Closing for now to stay inside the 3-concurrent-PR policy (see the discussion on #422). Nothing is wrong with the change and CI is green on it; I will reopen it as review slots free.

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