Skip to content

fix(ipc): bound native dispose() with a timeout so job children always exit#1906

Open
rinarakaki wants to merge 1 commit into
livekit:mainfrom
rinarakaki:fix/bound-native-dispose-timeout
Open

fix(ipc): bound native dispose() with a timeout so job children always exit#1906
rinarakaki wants to merge 1 commit into
livekit:mainfrom
rinarakaki:fix/bound-native-dispose-timeout

Conversation

@rinarakaki

Copy link
Copy Markdown

Closes #1905.

Problem

The process job child awaits dispose() (native FFI teardown) without a timeout before process.exit(0) (agents/src/ipc/job_proc_lazy_main.ts). If native disposal hangs on a handle that never drains, the child never exits — it lingers indefinitely holding the job's full RSS while still answering supervisor pings, so neither the orphan reaper nor the no-op SIGTERM handler reclaims it. On a long-running fleet these accumulate into a multi-day memory climb and eventual OOM. Full production trace in #1905.

Fix

Race dispose() against a DISPOSE_TIMEOUT (10s) and fall through to process.exit(0) on expiry. dispose() is still attempted first, so the normal path keeps the libc++abi-crash guard (livekit/node-sdks#564) intact; the timeout only changes the pathological case from "hang forever" to "exit anyway". A crash on exit is strictly preferable to an immortal zombie holding the job's full RSS.

Notes

  • Adds a changeset (@livekit/agents patch).
  • Happy path is unchanged (dispose() resolves well under 10s); the timeout only fires when disposal is genuinely wedged.

🤖 Generated with Claude Code

…s exit

The process job child awaits dispose() (native FFI teardown) without a timeout
before process.exit(0). If native disposal hangs on a handle that never drains,
the child never exits and lingers indefinitely holding the job's full RSS while
still answering supervisor pings, so neither the orphan reaper nor the no-op
SIGTERM handler reclaims it.

Race dispose() against DISPOSE_TIMEOUT (10s) and fall through to process.exit(0)
on expiry. dispose() is still attempted first, preserving the libc++abi guard
(livekit/node-sdks#564) on the normal path; the timeout only turns the
pathological hang-forever case into exit-anyway.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 19773f6

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

This PR includes changesets to release 35 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai 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

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

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.

Job child process can hang indefinitely in unbounded await dispose() and never reach process.exit(0)

2 participants