Don't trip the AI circuit breaker on load shedding

With many simultaneous games, AI turns start in bursts and exceed the
in-flight cap. That was counted as an AI failure, so after 5 bursts the
breaker paused the AI for 30 s and every AI seat played random moves.

- Only real failures (timeouts, lost connection, malformed/illegal
  answers, unexpected errors) count towards the breaker; the in-flight
  cap and "overloaded"/"expired" answers from the AI service do not
- AI_MAX_INFLIGHT default 32 -> 64 (>= MAX_ACTIVE_GAMES, matches the AI
  service's AI_MAX_QUEUE)
- Test that load shedding keeps the breaker closed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 13:04:21 +02:00
co-authored by Claude Opus 5.5
parent 87dfcd55b7
commit 763c5678f1
3 changed files with 58 additions and 7 deletions
+3 -1
View File
@@ -69,7 +69,9 @@ class Settings:
# --- AI service protection ----------------------------------------------
# Unanswered decide requests per AI connection before falling back.
ai_max_inflight: int = _int("AI_MAX_INFLIGHT", 32)
# Each running game has at most one AI deciding at a time, so keep this at
# least MAX_ACTIVE_GAMES; 64 matches the AI service's AI_MAX_QUEUE.
ai_max_inflight: int = _int("AI_MAX_INFLIGHT", 64)
# Consecutive AI failures that pause AI requests for ai_breaker_cooldown seconds.
ai_breaker_failures: int = _int("AI_BREAKER_FAILURES", 5)
ai_breaker_cooldown: float = _float("AI_BREAKER_COOLDOWN", 30.0)