fix(mcp-gateway): address critical issues from deep review

Frontend:
- Fix debounce race condition in UserListTable search handler
- Use useRef to properly track and cleanup timeout between keystrokes

Backend (LLM Gateway):
- Add thread-safe double-checked locking for global singletons
  (providers, circuit registry, cost tracker)
- Fix Redis URL parsing with proper urlparse validation
- Add explicit error handling for malformed Redis URLs
- Document circuit breaker state transition safety

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-04 01:36:55 +01:00
parent f6194b3e19
commit 95342cc94d
4 changed files with 122 additions and 35 deletions

View File

@@ -6,7 +6,9 @@ Configures the LiteLLM Router with model lists and failover chains.
import logging
import os
import threading
from typing import Any
from urllib.parse import urlparse
import litellm
from litellm import Router
@@ -57,19 +59,47 @@ def configure_litellm(settings: Settings) -> None:
def _parse_redis_host(redis_url: str) -> str:
"""Extract host from Redis URL."""
# redis://host:port/db
url = redis_url.replace("redis://", "")
host_port = url.split("/")[0]
return host_port.split(":")[0]
"""
Extract host from Redis URL.
Args:
redis_url: Redis connection URL (e.g., redis://localhost:6379/0)
Returns:
Hostname extracted from URL
Raises:
ValueError: If URL is malformed or missing host
"""
try:
parsed = urlparse(redis_url)
if not parsed.hostname:
raise ValueError(f"Invalid Redis URL: missing hostname in '{redis_url}'")
return parsed.hostname
except Exception as e:
logger.error(f"Failed to parse Redis URL: {e}")
raise ValueError(f"Invalid Redis URL: {redis_url}") from e
def _parse_redis_port(redis_url: str) -> int:
"""Extract port from Redis URL."""
url = redis_url.replace("redis://", "")
host_port = url.split("/")[0]
parts = host_port.split(":")
return int(parts[1]) if len(parts) > 1 else 6379
"""
Extract port from Redis URL.
Args:
redis_url: Redis connection URL (e.g., redis://localhost:6379/0)
Returns:
Port number (defaults to 6379 if not specified)
Raises:
ValueError: If URL is malformed
"""
try:
parsed = urlparse(redis_url)
return parsed.port or 6379
except Exception as e:
logger.error(f"Failed to parse Redis URL: {e}")
raise ValueError(f"Invalid Redis URL: {redis_url}") from e
def _is_provider_available(provider: Provider, settings: Settings) -> bool:
@@ -310,19 +340,28 @@ class LLMProvider:
return _is_provider_available(model_config.provider, self._settings)
# Global provider instance (lazy initialization)
# Global provider instance with thread-safe lazy initialization
_provider: LLMProvider | None = None
_provider_lock = threading.Lock()
def get_provider() -> LLMProvider:
"""Get the global LLM Provider instance."""
"""
Get the global LLM Provider instance.
Thread-safe with double-checked locking pattern.
"""
global _provider
if _provider is None:
_provider = LLMProvider()
with _provider_lock:
# Double-check after acquiring lock
if _provider is None:
_provider = LLMProvider()
return _provider
def reset_provider() -> None:
"""Reset the global provider (for testing)."""
global _provider
_provider = None
with _provider_lock:
_provider = None