Skip to content

fix(rtc): send and receive data packets without a new ctypes array type - #912

Merged
cloudwebrtc merged 1 commit into
livekit:mainfrom
zek:fix-publish-data-array-type
Nov 2, 2026
Merged

cloudwebrtc merged 1 commit into
livekit:mainfrom
zek:fix-publish-data-array-type

Conversation

@zek

@zek zek commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Closes #911.

publish_data and the data packet receive path built a ctypes.c_byte * data_len array type for each new payload length. On Python 3.12 and 3.13 the receive side keeps these types alive for the life of the process (the ctypes.POINTER() cache holds them). On Python 3.14 each type is cyclic garbage.

  • Send side: pass the address of the bytes payload with get_address. The native library copies the data during the request, as fix(rtc): pass the FFI request bytes without a new ctypes array type #847 already relies on in FfiClient.request. This also removes the per-byte (*payload) unpack.
  • Receive side: read the buffer with ctypes.string_at, as FfiClient does for event buffers.

The new test test_publish_data_makes_no_ctypes_array_type sends 10 payloads of new lengths, waits for the receiver to get them, and makes sure that no array type with these lengths exists. It also makes sure that the received payloads are intact.

Before and after

repro.py from #911, against a local LiveKit server (v1.13.5). The "this branch" rows use the branch source with the native library from the livekit 1.2.0 wheel:

LIVEKIT_LIB_PATH=<site-packages>/livekit/rtc/resources/liblivekit_ffi.dylib PYTHONPATH=livekit-rtc \
  uv run --no-project --python 3.12 --with livekit==1.2.0 --with livekit-api repro.py
Python livekit 1.2.0 this branch
3.12.12 freed by gc.collect(): 0, array types still alive: 100 0, 0
3.14.3 freed by gc.collect(): 1300, array types still alive: 0 0, 0

Tests (livekit-rtc/tests/test_dc.py):

main this branch
test_publish_data_makes_no_ctypes_array_type fails, 20 array types (10 send, 10 receive) passes
other test_dc.py and test_ffi_client.py tests 6 passed

publish_data built a `ctypes.c_byte * data_len` array type for each new
payload length, and the data packet receive path did the same with
`ctypes.POINTER(ctypes.c_byte * data_len)`. Each ctypes array type is a
reference cycle, so every packet of a new length left garbage that only
the cyclic garbage collector can free.

Pass the address of the bytes payload directly on the send side, and read
the received buffer with ctypes.string_at, as FfiClient.request already does.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-28T18:31:12.567411Z
We couldn’t complete this review. Comment @codex review to try again.
8116d3f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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.

Devin Review

@cloudwebrtc cloudwebrtc 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.

lgtm!

@cloudwebrtc
cloudwebrtc merged commit 4b8d2bd into livekit:main Nov 2, 2026
40 checks passed
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.

Data packets create a ctypes array type for each new payload length

2 participants