Skip to content

Room.connect FFI subscription is unfiltered; audio_stream_event fans out O(rooms × events) and starves the asyncio loop #812

Description

@wizd

Summary

PR #564 added filter_fn to FfiQueue.subscribe() and applied it to AudioStream / VideoStream. Room.connect() still does an unfiltered long-lived subscribe:

self._ffi_queue = FfiClient.instance.queue.subscribe(self._loop)

Room._listen_task only consumes room_event and rpc_method_invocation, then always does put_nowait + await self._room_queue.join(). Every audio_stream_event is therefore delivered to every connected Room and costs a full event-loop round-trip each time.

Production impact

We run many 1:1 voice rooms in one Python process (device WebSocket gateway → rtc.Room per session). With default 10 ms audio frames:

  • 8 rooms: ~7.5k listen-task wakeups/s — barely holds
  • 16 rooms: ~30k wakeups/s — event loop saturates

Symptoms match #564 and #390: room.connect() futures convoy-resolve after 10–60 s, WebSocket keepalive pings time out, CPU is idle (GIL / single loop), not compute-bound.

AudioSource.capture_frame() is a short-lived subscribe waiting on capture_audio_frame (the request callback), so it should not be filtered to audio_source_event.

Suggested fix

In Room.connect(), subscribe with a filter matching what _listen_task actually reads:

self._ffi_queue = FfiClient.instance.queue.subscribe(
    self._loop,
    filter_fn=lambda e: e.WhichOneof(message) in (room_event, rpc_method_invocation),
)

This is the same pattern as #564, just completing it for Room. Happy to send a PR if that helps.

Environment

  • livekit==1.1.8 / livekit-api==1.1.0
  • one process, many rtc.Room instances
  • no frame_size_ms on AudioStream (defaults to 10 ms)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions