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,6 +6,7 @@ Provides aggregation by hour, day, and month with TTL-based expiry.
"""
import logging
import threading
from datetime import UTC, datetime, timedelta
from typing import Any
@@ -441,27 +442,37 @@ def calculate_cost(
return round(input_cost + output_cost, 6)
# Global tracker instance (lazy initialization)
# Global tracker instance with thread-safe lazy initialization
_tracker: CostTracker | None = None
_tracker_lock = threading.Lock()
def get_cost_tracker() -> CostTracker:
"""Get the global cost tracker instance."""
"""
Get the global cost tracker instance.
Thread-safe with double-checked locking pattern.
"""
global _tracker
if _tracker is None:
_tracker = CostTracker()
with _tracker_lock:
# Double-check after acquiring lock
if _tracker is None:
_tracker = CostTracker()
return _tracker
async def close_cost_tracker() -> None:
"""Close the global cost tracker."""
global _tracker
if _tracker:
await _tracker.close()
_tracker = None
with _tracker_lock:
if _tracker:
await _tracker.close()
_tracker = None
def reset_cost_tracker() -> None:
"""Reset the global tracker (for testing)."""
global _tracker
_tracker = None
with _tracker_lock:
_tracker = None