Skip to content

fix(controller): don't fail the losing racer of a concurrent wakeup_model() call - #409

Open
AmirF194 wants to merge 3 commits into
ovg-project:mainfrom
AmirF194:fix/wakeup-model-concurrent-race
Open

fix(controller): don't fail the losing racer of a concurrent wakeup_model() call#409
AmirF194 wants to merge 3 commits into
ovg-project:mainfrom
AmirF194:fix/wakeup-model-concurrent-race

Conversation

@AmirF194

Copy link
Copy Markdown
Contributor

Fixes #408.

wakeup_model() checks model_name in self.sleeping_models, awaits the
real upstream wake call, then does del self.sleeping_models[model_name].
That dict has exactly two writers in the package (put_model_to_sleep sets
it, wakeup_model deleted it): no lock guards the check-then-mutate across
the await. Two concurrent wakeup_model() calls for the same model both
pass the membership check, both call their own real upstream wake API, and
both reach the del. Only the first succeeds; the second raises
KeyError, caught by the surrounding except Exception, so that caller
reports False even though its own upstream wake call succeeded.

Fix: self.sleeping_models.pop(model_name, None) instead of del. The
losing racer no longer raises, so both callers reach return True, which
is correct since both of their own upstream calls succeeded.

Verified in a clean python:3.11-slim container at HEAD (b55096c):
tests/test_wakeup_race.py fires two concurrent wakeup_model() calls
with a mocked (always-succeeding) upstream wake API. Before the fix:
[True, False]. After: [True, True]. The mock only replaces the
upstream HTTP call, not sleeping_models or either of its two writers.

Also ran the repo's own gates on the changed files: pre-commit run
(ruff, codespell, isort, SPDX header check, trailing-whitespace, local
mypy) and the CI-only mypy-3.12 manual hook, all passing.

Not verified: behavior against the real vLLM/SGLang wake APIs (only the
mocked upstream call), and whether two concurrent upstream wake calls to
the same backend are themselves safe to fire together, that's existing
behavior this change does not touch.

…odel() call

del self.sleeping_models[model_name] raises KeyError when two wakeup_model()
calls for the same model race: both pass the sleeping-membership check,
both await their own real upstream wake call, and only the first del
succeeds. The second caller's KeyError is caught by the surrounding
except Exception and turned into a spurious False, even though its own
upstream wake call succeeded.

Use self.sleeping_models.pop(model_name, None) instead, so the losing
racer no longer raises and both callers report the true outcome of their
own upstream call.

Fixes ovg-project#408
Copilot AI review requested due to automatic review settings July 23, 2026 18:43
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@AmirF194

Copy link
Copy Markdown
Contributor Author

No rush, just a check-in after a week. Pre-commit CI is still awaiting approval to run on this fork PR, nothing has executed yet.

@AmirF194

Copy link
Copy Markdown
Contributor Author

Closing to keep the queue clean; happy to reopen if there's interest.

@AmirF194 AmirF194 closed this Aug 23, 2026
@AmirF194 AmirF194 reopened this Aug 23, 2026
@AmirF194

Copy link
Copy Markdown
Contributor Author

Reopening. My previous close was a mistake on my end, this is still open work and I'd like to see it through.

@AmirF194

Copy link
Copy Markdown
Contributor Author

Closing to keep the queue clean, no maintainer signal in a month. Happy to reopen if there is interest, the branch stays up.

@AmirF194 AmirF194 closed this Aug 26, 2026
@AmirF194 AmirF194 reopened this Aug 26, 2026
@AmirF194

Copy link
Copy Markdown
Contributor Author

Sorry, reopened. I closed this by mistake, it is still on the roadmap in #419 and nothing here needed closing.

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.

SleepManager.wakeup_model() reports failure for a caller whose own wake call actually succeeded, when two wakeups for the same model race

2 participants