fix: harden TTS with 2s await timeout and 4s worker timeout for reliable fallback

Reduces worker generation timeout from 10s to 4s and adds 2s race on
awaitReady so slow Kokoro generation falls back to Web Speech API
quickly instead of stalling the fight.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-09 10:18:03 +00:00
co-authored by Claude Opus 4.6
parent cb8a1d50fe
commit 4c17379ad4
+7 -4
View File
@@ -252,7 +252,7 @@ function _workerGenerate(text: string, voice: string, speed: number): Promise<{
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
_pending.delete(id) _pending.delete(id)
reject(new Error('TTS generation timed out')) reject(new Error('TTS generation timed out'))
}, 10_000) }, 4_000)
_pending.set(id, { _pending.set(id, {
resolve: (v) => { clearTimeout(timeout); resolve(v) }, resolve: (v) => { clearTimeout(timeout); resolve(v) },
reject: (e) => { clearTimeout(timeout); reject(e) }, reject: (e) => { clearTimeout(timeout); reject(e) },
@@ -376,12 +376,15 @@ export function kokoroPrefetch(text: string, profileName: string): void {
_generateAndCache(text, profileName).catch(() => {}) _generateAndCache(text, profileName).catch(() => {})
} }
/** Await until prefetched audio is cached and ready. Returns true if cached, false on failure. */ /** Await until prefetched audio is cached and ready (max 2s). Returns true if cached, false on timeout/failure. */
export async function kokoroAwaitReady(text: string, profileName: string): Promise<boolean> { export async function kokoroAwaitReady(text: string, profileName: string): Promise<boolean> {
if (!_workerReady) return false if (!_workerReady) return false
try { try {
const buf = await _generateAndCache(text, profileName) const result = await Promise.race([
return !!buf _generateAndCache(text, profileName),
new Promise<null>(r => setTimeout(() => r(null), 2000)),
])
return !!result
} catch { return false } } catch { return false }
} }