mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-29 06:33:28 +00:00
* fix(router): stop concurrent deployment deletes from crashing deployment lookups delete_deployment and upsert_deployment shrink model_list before they repair the index maps, so a lookup on another thread in that window read a stale index: IndexError, or the neighbouring deployment and its credentials. An add racing a delete could corrupt the index for good. One RLock now covers model_list and the three index maps. Delete, upsert, add and the set_model_list reset change them under it, and every lookup that turns an index into a deployment reads under it. Fixes #45242 * test(router): release the held delete when the read reaches the index lock The race tests released the held write after a fixed 0.2 s, so a reader the runner stalled past it read the repaired list and passed on unfixed code. The read now runs on its own thread and the write stays held until the read returns or reaches the router's index lock; the 10 s bound only fails a broken synchronization. The integration test gains the audit cells: chat, streaming, Responses and Anthropic messages calls (sync and async, by model name and team public name) during a held delete, the same for upsert, add and set_model_list, a request for the deployment being deleted, a provider error, a double delete, and thread and async bursts during upsert churn. * test(router): cover the early return of a delete and the team filter of get_model_ids delete_deployment now returns None from inside the index lock, and get_model_ids by name reads its deployments through _deployments_named; pin both: deleting an unknown id returns None and leaves the list alone, and exclude_team_models drops only the team deployment. * fix(router): read deployments by name under the index lock outside the Router The response polling provider check, the complexity router's adaptive pool and the savings baseline turned the name index into list positions themselves, so a concurrent delete could still hand them a stale slot. They now read through Router.deployments_named, which takes the deployment index lock. * fix(router): type the locked deployment lookups as DeploymentTypedDict deployments_named and _team_deployments_named returned tuple[Any, ...]. They now return DeploymentTypedDict rows, which is what model_list holds. The adaptive pool setup in the Router and the complexity router drop their branches for pydantic Deployment rows, which these lookups never return, and should_include_deployment accepts the typed row. --------- Co-authored-by: yucheng-berri <293926326+yucheng-berri@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| conftest.py | ||
| test_aiohttp_session_rebuild_wire.py | ||
| test_anthropic_messages_bridge_mid_stream_failure_sdk.py | ||
| test_azure_prompt_shield_tuple_messages.py | ||
| test_bedrock_converse_redacted_thinking_router_sdk.py | ||
| test_bedrock_converse_stream_sync_decoder_wire.py | ||
| test_bedrock_model_discovery_sdk.py | ||
| test_bedrock_native_output_fallback_sdk.py | ||
| test_bedrock_native_output_register_model_sdk.py | ||
| test_cache_control_census_pydantic_messages_sdk.py | ||
| test_caching_redis_sdk.py | ||
| test_callback_logging_cache.py | ||
| test_databricks_json_schema_refs_sdk.py | ||
| test_device_code_login_guard_sdk.py | ||
| test_dual_cache_redis.py | ||
| test_exa_search_envelope_sdk.py | ||
| test_gemini_long_decode_sync_sdk.py | ||
| test_gemini_tts_speech_logging_sdk.py | ||
| test_generic_api_callback.py | ||
| test_google_genai_adapter_stream_usage_sdk.py | ||
| test_http2_wire.py | ||
| test_huggingface_tokenizer_downloads_sdk.py | ||
| test_idle_upstream_reconnect_sdk.py | ||
| test_interception_converted_stream_options_sdk.py | ||
| test_langfuse_redaction_sdk.py | ||
| test_local_sandbox_sdk.py | ||
| test_ocr_matrix_sdk.py | ||
| test_openai_sdk_client_sessions_wire.py | ||
| test_owned_redis_ports.py | ||
| test_provider_budget_redis.py | ||
| test_provider_error_and_extra_body_families_wire.py | ||
| test_redis_breaker_metrics_multiprocess_sdk.py | ||
| test_redis_cluster_iam_auth.py | ||
| test_redis_service_metrics.py | ||
| test_response_cache_sync_sdk.py | ||
| test_responses_bridge_stream_errors_sdk.py | ||
| test_responses_bridge_sync_reasoning_sdk.py | ||
| test_responses_bridge_tool_search_sdk.py | ||
| test_router_behavior_wire.py | ||
| test_router_budget_limiter_wire.py | ||
| test_router_concurrent_deployment_delete_sdk.py | ||
| test_router_cooldown_fallback_sdk.py | ||
| test_router_include_fallback_errors_wire.py | ||
| test_router_lowest_latency_wire.py | ||
| test_router_redis_tls_url.py | ||
| test_router_sync_stream_fallback_wire.py | ||
| test_router_tool_call_stream_fallback_budget_wire.py | ||
| test_router_unsupported_params_fallback_wire.py | ||
| test_sagemaker_embedding_sdk.py | ||
| test_slack_daily_report_redis.py | ||
| test_stream_error_api_base_sdk.py | ||
| test_stream_open_error_provider_headers_sdk.py | ||
| test_sync_stream_connection_release_wire.py | ||
| test_text_completion_stream_rebuild_sdk.py | ||
| test_tool_loop_server_tool_replay_sdk.py | ||
| test_topaz_image_variation_trailing_slash_sdk.py | ||
| test_usage_based_routing_sdk_redis_reads.py | ||
| test_usage_routing_counter_ttl.py | ||
| test_vertex_batch_row_line_errors_sdk.py | ||
| test_vertex_gemini_image_batch_cost_sdk.py | ||
| test_vertex_gemini_stream_timeout_wire.py | ||
| test_vertex_partner_count_tokens_sdk.py | ||