[Bug]: engine:status re-runs the readiness probe under the engine lock on every call; a slow engine /health starves the model-list sweep and, polled ~1/s, leaked a TP=4 head to death
Les mainteneurs répondent en général sous 5 jours
@kjlubick y travaille déjà.
Depuis le 18/9/2026.
Évaluation
Cette issue n'a pas encore été évaluée.
Description
Area
Engine or model management
User problem
Every engine:status call re-runs the engine's readiness probe while holding that engine's lifecycle lock, and several PAIR components poll status independently. On an engine whose readiness endpoint is cheap that is invisible. On an engine whose /health does real work it has two consequences we hit in production this week on a 4-node tensor-parallel SGLang head (DGX Spark, GB10):
- Model-list starvation. The broker's advertiser (every 5 s), the loaded-model watcher (every 5 s) and the desktop's remote status poll (every 10 s) each call
engine:status.StatusAtPorttakesst.opMu, thenreconcilePresencerunsprobe(ready)andprobe(identity)with no caching. SGLang's/healthperforms a short generation and takes ~1.0 s on this build, so the mutex was held essentially 100% of the time andModelsResult's sweep (which needsStatusfirst) never got in.GET :14322/v1/modelson that node hung for 40 s+ indefinitely; peers piled up hundreds of CLOSE-WAIT sockets; the desktop loggedremote engine status ... unavailableevery 10 s. A standalone engine-manager with no broker traffic answered in 16 ms. Restarting engine-manager did not help. - The probe load itself leaked memory. The head's container log shows 72,144
GET /healthand 69,817GET /get_model_infoover a 20 h run, ~1/s each, with zero user requests for the final 30 min. The head's MemAvailable declined monotonically from 8.7 GB (00:20) to 2.5 GB (16:20) while the three worker ranks stayed flat, then earlyoom SIGTERMed the scheduler at 16:28 and the TP group died. After the crash the head returned to its idle baseline, so the growth was inside the front-end processes only rank 0 runs. Pointing the probes at/get_model_info(~1 ms, no generation) dropped/healthtraffic from ~3,500/h to the container's own healthcheck and the model list answers in 13 ms.
SGLang itself is not in develop yet (it lives in #50 and in my fork), but the mechanism is upstream code and applies to any engine whose readiness endpoint is not free; llama.cpp's /health under load and /v1/models on busy servers are candidates.
Where
services/nvpair-engine-manager/status.go:StatusAtPort→st.opMu.Lock()→reconcilePresence(context.Background(), ...)→e.probe(ctx, ready, port)thene.probe(ctx, identity, port)on every call.services/nvpair-engine-manager/models.go:ModelsResultcallse.Status(name)per engine before the 5 s action budget starts; the lock wait is unbounded.- Pollers:
nvpair-ui-broker/advertiser.go(autoAdvertiseInterval = 5 * time.Second),nvpair-engine-manager/loadedwatch.go(defaultLoadedPollSeconds = 5), the desktop's remote-get-installed loop.
Proposed fix
- Do not re-run the readiness probe for an engine that is already adopted and healthy with a live health loop; trust the health loop's last result, or cache presence for a few seconds.
- Do not take
opMufor the read-only status path; snapshot state, probe outside the lock. - Treat the manifest's
identityendpoint as the default readiness/health probe and require an explicit opt-in for anything that generates.
Workaround for operators
A per-engine manifest override (engines/sglang.json) pointing runtime.ready.http and runtime.health.http at /get_model_info, plus the advertiser change in https://github.com/jlacroix82/Personal-AI-Router/commit/c5b9be7 (on feat/vllm-sglang).
Environment
PAIR 0.1.1 services (engine-manager 0.21.0 / broker 0.42.2 as built from feat/vllm-sglang at ff26f5b), Linux arm64, DGX Spark x4 per TP group, SGLang lmsysorg/sglang:dev-dsv41 serving DeepSeek-V4.1-Flash. Related: #37 (probe connection reuse), #50 (SGLang engine), #24 (external backends).
- Langage dominant
- Go
- Étoiles
- 1.6k
- Forks
- 266
- Merge moyen
- 3 j 6 h
- PR mergées (30 j)
- 22
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de NVIDIA/Personal-AI-Router
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 20/100
NVIDIA/Personal-AI-Router#165 ·
Les mainteneurs répondent en général sous 5 jours
-
bug
Difficulté 4/5 3-5 jours Accessibilité débutants 46/100
NVIDIA/Personal-AI-Router#164 ·
Les mainteneurs répondent en général sous 5 jours
-
enhancement
Difficulté 4/5 Plus d'une semaine Accessibilité débutants 12/100
NVIDIA/Personal-AI-Router#162 ·
Les mainteneurs répondent en général sous 5 jours
-
enhancement
Difficulté 4/5 3-5 jours Accessibilité débutants 25/100
NVIDIA/Personal-AI-Router#154 · 1 commentaire ·
Les mainteneurs répondent en général sous 5 jours
-
[Feature]: [Ollama] Alert the user about model pull failuresPeut-être pris @ckelseynv l’a pris il y a 3 jours. Ouverteenhancement
Difficulté 3/5 1-2 jours Accessibilité débutants 56/100
NVIDIA/Personal-AI-Router#152 · 1 commentaire · 1 personne assignée ·
Les mainteneurs répondent en général sous 5 jours
Toutes les issues de NVIDIA/Personal-AI-Router
Issues similaires
-
darwin zsh
Difficulté 1/5 Moins d'une heure Accessibilité débutants 90/100
carapace-sh/carapace-bin#3846 ·
Les mainteneurs répondent en général sous 1 jour
-
appplication - is a typo?Ouverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 70/100
golang-app/ecommerce#179 ·
Les mainteneurs répondent en général sous 1 jour
-
Simulator process crashes (nil pointer panic) when the dataset returns an errorPeut-être pris @EugeneVon l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
llm-d/llm-d-inference-sim#772 ·
Les mainteneurs répondent en général sous 1 jour
-
refactor: decode numchildren with a lenient int type instead of a hand-written xProp.UnmarshalXMLOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
crazy-goat/xdbg#125 ·
Les mainteneurs répondent en général sous 1 jour
-
150 points ci complexity:medium drips-wave help wanted medium
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
sorotrail/SoroBeacon#449 ·
Les mainteneurs répondent en général sous 1 jour