Skip to content

[OPTIMIZATION] Blocking Synchronous Process Wait in ASR WebSocket Handler Freezes FastAPI Event Loop #1968

Description

@dipexplorer

Problem

The speech-to-text (ASR) microservice in apps/ml/routers/asr.py handles real-time audio streams via WebSockets. To transcode arbitrary browser audio formats, it spawns an ffmpeg subprocess using subprocess.Popen.

When the WebSocket disconnects (or finishes), session.close() is called, which invokes StreamingAudioDecoder.close(). This method calls _wait_for_process_exit() (line 548).

_wait_for_process_exit contains multiple synchronous, blocking calls to self._process.wait(timeout=0.2). Because FastAPI/Uvicorn runs on a single event loop thread, executing blocking code like subprocess.wait() halts the entire event loop. If a client disconnects abruptly, the event loop freezes for up to 0.6 seconds. This prevents the server from handling any other requests, creating a critical performance bottleneck and potential Denial of Service (DoS) vulnerability.

Proposed Changes

  1. Modify apps/ml/routers/asr.py:
    • Avoid synchronous blocking waits on the event loop thread.
    • Use FastAPI/anyio's thread offloader to run the close/wait process in a worker thread:
      from anyio.to_thread import run_sync
      await run_sync(self.decoder.close)
    • Alternatively, use Python's asyncio.create_subprocess_exec to manage the subprocess asynchronously and await process.wait() natively.

Acceptance Criteria

  • WebSocket disconnections do not block the FastAPI event loop.
  • The StreamingAudioDecoder process terminates cleanly without leaving zombie processes.
  • High-concurrency tests show that multiple simultaneous WebSocket connections/disconnections do not degrade HTTP route response times.

⚠️ Contributor Instructions (Please Read Carefully)

  • Do NOT spam "/assign" or "Please assign me".
  • To claim this task, you MUST reply with a brief proposed implementation plan/approach. What files will you touch? How will you solve it?
  • Once your approach is reviewed and approved by a maintainer, you will be officially assigned.
  • Any PR opened without prior assignment and approach approval will be closed.

Metadata

Metadata

Type

No type

Projects

Status
🎉 Merged

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions