Repository navigation
fix(proxy): keep externally-managed deployments across config reconcile - #42218
Rainmemery wants to merge 2 commits into
Conversation
The 30s reconcile in _delete_deployment evicts every router deployment absent from both the DB and config.yaml. A deployment injected at runtime (by a plugin, callback or set_model_list/upsert_deployment) meets exactly that condition, so with store_model_in_db on it is silently deleted within seconds. Let a deployment declare an external owner via model_info.managed_by: such a deployment is not an orphan of the DB+config reconcile, so the cleanup loop skips it (with a log line) instead of evicting it. Deployments without an owner and unknown to DB/config are still removed as before. Adds regression coverage: an externally-managed deployment survives the reconcile when config.yaml lists other models, while an owner-less orphan is still evicted.
_delete_deployment now skips deployments declaring an external owner via model_info.managed_by. These pre-existing tests use MagicMock routers whose get_deployment returns an auto-created (truthy) mock, which the new skip branch misread as a managed deployment, suppressing expected evictions. Pin get_deployment.return_value to None so the ids are treated as unknown to the router - the correct condition under which they must still be evicted.
|
CI status: all functional checks pass (proxy-infra Run tests: success, plus all other shards). The only failing check is the repo-wide lint job, which fails on GitHub runner infra (Node 20 deprecation) for every contributor PR at the moment - no code-related annotations. Local |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
PR Architectural ReviewThe change correctly addresses the eviction of externally managed deployments during the periodic 30s background reconciliation cycle ( Key Validation Points:
Overall a solid and necessary fix for hybrid proxy deployments. |
|
@chilkotiKartik thanks for the detailed review! Quick notes on your three validation points:
Open to reworking if maintainers prefer a different shape. |
|
#42218 closing in favor of #42214 — @Pawan-Shahane's PR solves the same issue (#42211, runtime-injected deployments evicted by config reconcile) with the same |
Fixes #42211.
What
With
store_model_in_db: true, the 30s config reconcile in_delete_deploymentevicts every router deployment absent from both the DB andconfig.yaml:A deployment injected into the Router at runtime - by a plugin, callback, or any caller of
set_model_list/upsert_deployment- is in that exact condition, so it is silently deleted within seconds. Nothing is logged at any level.Fix
Allow a deployment to declare an external owner via
model_info.managed_by. During deletion, such a deployment is treated as "not an orphan": the cleanup loop skips it (with an info-level log line) instead of evicting it. Deployments with no owner that are unknown to both DB and config are still removed, so existing behavior is unchanged.model_infoalready round-trips arbitrary keys through the Router, somanaged_byis readable viaget_deployment(...).model_infoafterset_model_list.Testing
Local run, network-free and DB-free:
tests/test_litellm/proxy/test_delete_deployment_managed_by.py:config.yamllists only other models;tests/test_litellm/proxy/test_update_llm_router_resilience.pyupdated: the mock router'sget_deploymentreturnsNonefor a stale id, which must not shield it from eviction.Result:
9 passedacross both files.