From ae61c8c75afae858827d93c5866e499673ab85cb Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 8 Apr 2026 12:43:49 -0700 Subject: [PATCH] Fix Start button not updating: unblock the event loop start_transcription() blocks up to 15s waiting for the Deepgram WebSocket to connect. Running it synchronously in the async endpoint blocked the entire uvicorn event loop, preventing: - pollStatus from completing (frozen HTTP request) - WebSocket broadcasts from being sent - Any other API requests from being handled Fix: run start/stop/reload in thread pool via run_in_executor so the event loop stays responsive during long-running operations. Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/api_server.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/backend/api_server.py b/backend/api_server.py index 23a5867..fa5c583 100644 --- a/backend/api_server.py +++ b/backend/api_server.py @@ -151,14 +151,24 @@ class APIServer: @app.post("/api/start") async def start_transcription(): - success, message = ctrl.start_transcription() + import asyncio + # Run in thread pool to avoid blocking the event loop + # (start_recording can block up to 15s waiting for Deepgram WS) + loop = asyncio.get_event_loop() + success, message = await loop.run_in_executor( + None, ctrl.start_transcription + ) if not success: raise HTTPException(status_code=400, detail=message) return {"status": "ok", "message": message} @app.post("/api/stop") async def stop_transcription(): - success, message = ctrl.stop_transcription() + import asyncio + loop = asyncio.get_event_loop() + success, message = await loop.run_in_executor( + None, ctrl.stop_transcription + ) if not success: raise HTTPException(status_code=400, detail=message) return {"status": "ok", "message": message} @@ -223,7 +233,11 @@ class APIServer: @app.post("/api/reload-engine") async def reload_engine(): - success, message = ctrl.reload_engine() + import asyncio + loop = asyncio.get_event_loop() + success, message = await loop.run_in_executor( + None, ctrl.reload_engine + ) if not success: raise HTTPException(status_code=500, detail=message) return {"status": "ok", "message": message}