Speaker: højst tre samtidige kald til ElevenLabs og nyt forsøg ved 429
CI / test (push) Successful in 24s

Afsløringen bestilte alle trin på én gang og ramte abonnementets loft for
samtidige kald. Forklaringen genereres nu allerede, mens der løjes.

Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
This commit is contained in:
agw
2026-10-01 21:58:30 +02:00
parent d2dfeafea0
commit 6f8370fb96
2 changed files with 22 additions and 1 deletions
+3
View File
@@ -124,6 +124,9 @@ class Room:
self.say(text)
if ev["type"] == "lie_start":
self._at_deadline_minus(10, "lie", "lie_hurry")
note = (self.game.question or {}).get("note")
if note: # forklaringen kendes allerede nu; lav den, mens der løjes
asyncio.get_running_loop().create_task(tts.synth(note))
elif ev["type"] == "guess_start":
self._at_deadline_minus(5, "guess", "guess_hurry")
+19 -1
View File
@@ -19,7 +19,10 @@ log = logging.getLogger(__name__)
API = "https://api.elevenlabs.io/v1/text-to-speech/{voice}?output_format=mp3_44100_128"
BITRATE = 128_000
CONCURRENCY = 3 # ElevenLabs begrænser samtidige kald pr. abonnement (Creator: få)
RETRIES_ON_429 = 3
_inflight: dict[str, asyncio.Future] = {}
_sem: asyncio.Semaphore | None = None
def enabled() -> bool:
@@ -74,7 +77,7 @@ async def synth(text: str) -> dict | None:
return _result(digest)
fut = _inflight.get(digest)
if fut is None:
fut = asyncio.get_running_loop().create_task(asyncio.to_thread(_fetch, text, cache_path(digest)))
fut = asyncio.get_running_loop().create_task(_fetch_limited(text, cache_path(digest)))
_inflight[digest] = fut
fut.add_done_callback(lambda _f: _inflight.pop(digest, None))
try:
@@ -85,6 +88,21 @@ async def synth(text: str) -> dict | None:
return _result(digest)
async def _fetch_limited(text: str, path: Path) -> None:
global _sem
if _sem is None:
_sem = asyncio.Semaphore(CONCURRENCY)
for attempt in range(RETRIES_ON_429 + 1):
async with _sem:
try:
await asyncio.to_thread(_fetch, text, path)
return
except urllib.error.HTTPError as e:
if e.code != 429 or attempt == RETRIES_ON_429:
raise
await asyncio.sleep(0.7 * (attempt + 1))
def _describe(e: Exception) -> str:
if isinstance(e, urllib.error.HTTPError):
try: