Repository navigation
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a contained, tested fix that retries late workers, cleans replacement indexes and policy counts, and adds only an additive worker-models response field. The supplied unresolved Medium findings are at the repository’s blocking threshold, although the corresponding paths appear addressed in the current diff. Notes:
You can add or adjust custom eligibility rules. Learn more. |
aniravich
force-pushed
the
fix/late-worker-model-discovery
branch
from
September 26, 2026 21:55
ab4e5b4 to
46dcf3f
Compare
aniravich
force-pushed
the
fix/late-worker-model-discovery
branch
from
September 26, 2026 22:15
46dcf3f to
1989b9a
Compare
A worker that isn't serving when the router starts is registered under the 'unknown' placeholder model, and requests that name a model only reach workers indexed under it. The late worker got none of that traffic until the model refresh on every 5th health check (4 minutes after startup at the default 60s interval), while sticky sessions pinned to the early workers; in prime-rl job 1498 all 335 opening sessions landed on 2 of 16 servers. The health checker now re-reads /v1/models on every check for workers still under the placeholder; the rest keep the 5-check refresh for LoRA changes. GET /workers also reports each worker's live models, since model_id is fixed at registration and kept showing 'unknown' after routing recovered. Model refreshes run concurrently, at most 32 at a time, and each result is applied as it arrives, so unreachable workers cost a health-check cycle one 5s request timeout in total rather than one each. Registering a worker at a URL that is already registered now removes the old worker from every index first, so the models discovered for it don't carry over to the replacement. Registration, removal and model syncs now take one registry lock, so a model sync that races a replacement or removal can't put the dropped worker back into the model index. Replacing a worker now hands back the worker it replaced, and the router manager releases that worker's model from its policy counts before counting the replacement; removal releases the model of the worker actually removed. A worker indexed only under the placeholder, even more than once, is retried on every check.
aniravich
force-pushed
the
fix/late-worker-model-discovery
branch
from
September 26, 2026 22:39
1989b9a to
ad1f4b1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
A worker that isn't serving when the router starts is registered under the placeholder model
unknown, and requests that name a model only reach workers indexed under it. Such a worker got none of that traffic until the model refresh on every 5th health check (4 minutes after startup at the default 60 s interval), while sticky sessions pinned to the early workers. On a prime-rl RL run with 16 vLLM servers, all 335 opening sessions landed on 2 of them and 59% of the step-0 eval failed./v1/modelson every check for workers still in no real model's pool, i.e. listed only under the placeholder. Everyone else keeps the 5-check refresh, which picks up LoRA changes. Fetches run concurrently (at most 32 in flight, one per DP base URL) and each result is applied as it arrives, so unreachable workers cost a cycle one 5 s request timeout in total, not one each./workersreports live models.GET /workersandWorkerInfogain amodelsfield.model_idstays the label fixed at registration, which kept showingunknownafter routing had recovered.register(through the newregister_replacing) removes the old worker from every index first, including its discovered models, and returns it.RouterManagerthen releases the old worker's policy count before counting the replacement, and removal releases the model of the worker actually removed.register,removeandsync_worker_modelstake one lock; reads stay lock-free. A model sync that races a replacement or removal can no longer put the dropped worker back into the model index.Behavior change: registering a worker at an already-registered URL now fully replaces it. Previously the old worker stayed in its old model indexes, and its policy count was never released.
prime-rl also starts the router only once all its workers are healthy (PrimeIntellect-ai/prime-rl#3687). This PR covers workers that still aren't serving when the router starts, for example with other launchers.
Test Plan
cargo fmt --check,cargo clippy --all-targets -- -D warnings(Rust 1.95.0) andcargo test.test_late_worker_joins_model_index_on_next_health_check,test_reregistering_url_replaces_discovered_models,test_has_unknown_model_ignores_duplicate_placeholders,test_replacing_worker_rebalances_policy_counts.--health-check-interval-secs 5; time until the late worker is indexed under its model, compared with the v0.2.1 wheel. Re-run on the final commit with the router binary.Test Result
/workersreports"models": ["m"]for it whilemodel_idstaysunknown./v1/modelswave), and the late worker joins its model 1 s after the health checker starts.model_index; with it, the re-registration waits for the sync and nothing stale remains. The stress run finishes without deadlock, and every indexed worker is the one registered at its URL, listed once per model./workerslisted all 16 with"models": ["Qwen/Qwen3.8-27B"]. prime-rl's launcher gate was also in place, so the late-worker path itself wasn't exercised in that run.Essential Elements of an Effective PR Description Checklist