Skip to content

Fix fire-and-forget event tasks in RealtimeSession#3553

Open
kratos0718 wants to merge 1 commit into
openai:mainfrom
kratos0718:fix/floating-tasks-in-realtime-session
Open

Fix fire-and-forget event tasks in RealtimeSession#3553
kratos0718 wants to merge 1 commit into
openai:mainfrom
kratos0718:fix/floating-tasks-in-realtime-session

Conversation

@kratos0718
Copy link
Copy Markdown

Summary

RealtimeSession emitted three error events via a bare asyncio.create_task(self._put_event(...)) whose result was discarded (in _on_guardrail_task_done and _on_tool_call_task_done).

asyncio only keeps a weak reference to a task, so a fire-and-forget task can be garbage-collected before it runs (documented behavior). When that happens here, the error event it was meant to deliver is silently dropped — and these are exactly the paths that report guardrail/tool-call failures to the caller.

The session already uses a keep-a-reference pattern for _guardrail_tasks and _tool_call_tasks (a tracking set + add_done_callback(discard)). This change applies the same pattern to the event-emitting tasks via a small _emit_event_soon helper, and cancels any still-pending event tasks during _cleanup.

Test plan

  • Added tests/realtime/test_session_event_tasks.py:
    • _emit_event_soon holds a strong reference while the task is pending, delivers the event to the queue, and releases the reference once done.
    • _cleanup_event_tasks cancels pending event tasks.
  • make format, make lint pass (ruff).

Issue number

N/A — found via static analysis of fire-and-forget create_task usage.

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation (n/a — internal behavior)
  • I've run make lint and make format
  • I've made sure tests pass

Three error events were emitted with a bare asyncio.create_task(self._put_event(...))
whose result was discarded. asyncio only keeps a weak reference to a task, so
these tasks could be garbage-collected before running, silently dropping the
error events they were meant to deliver.

Route them through a new _emit_event_soon helper that retains a strong reference
in a tracking set until the task completes (mirroring the existing
_guardrail_tasks and _tool_call_tasks pattern), and cancel any pending event
tasks during cleanup. Adds regression tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants