Skip to content

fix: cancel losing timeout in AudioMixer race to prevent timer leak#641

Open
LautaroPetaccio wants to merge 3 commits intolivekit:mainfrom
LautaroPetaccio:fix/audio-mixer-timeout-cleanup
Open

fix: cancel losing timeout in AudioMixer race to prevent timer leak#641
LautaroPetaccio wants to merge 3 commits intolivekit:mainfrom
LautaroPetaccio:fix/audio-mixer-timeout-cleanup

Conversation

@LautaroPetaccio
Copy link
Copy Markdown

Why

AudioMixer.getContribution() uses Promise.race([iterator.next(), this.timeout(ms)]) to race each stream against a deadline. When the iterator wins (the normal case), the losing timeout's setTimeout is never cleared. It fires harmlessly but creates an orphaned timer on every mixing iteration. Under sustained mixing this creates a steady stream of wasted work, and in pathological cases can pressure the timer heap.

How

Replace the old timeout() method (which returned an uncancellable promise) with timeoutRace(), which returns both the race promise and a clearTimeout handle. After the race resolves in getContribution(), cancel() is called immediately to clear the losing timer.

Test coverage

Three new unit tests in audio_mixer.test.ts:

  • completes mixing without lingering timers when iterator is fast — verifies mixing works correctly with a long timeout that always loses the race
  • produces frames even with many race iterations — stress test with more frames and iterations
  • handles slow streams via timeout path — uses a 1ms timeout with a slow stream to verify the timeout path works and logs the expected warning

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

🦋 Changeset detected

Latest commit: 54d5d36

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@livekit/rtc-node Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant