Skip to content

Improved data tracks depacketizer to support mutliple in flight packets#1923

Open
1egoman wants to merge 7 commits intomainfrom
improved-depacketizer
Open

Improved data tracks depacketizer to support mutliple in flight packets#1923
1egoman wants to merge 7 commits intomainfrom
improved-depacketizer

Conversation

@1egoman
Copy link
Copy Markdown
Contributor

@1egoman 1egoman commented Apr 27, 2026

  • Updates the depacketizer to take a maxPartialFrames which controls how many frames are being stored at once.
  • Exposes this as a RemoteDataTrack level setting - there is one pipeline per track, not one pipeline per subscription, so this is where it makes most sense (also given that you won't really need to configure it differently by subscription since this is fully dependant on the data being received from the sender).

Code example:

const remoteDataTrack: RemoteDataTrack = /* ... */;

// The new bit:
remoteDataTrack.setMaxPartialFrames(10); // Defaults to 1 to maintain backwards compatibility.

for await (const frame of remoteDataTrack.subscribe()) {
  // ...
}

Todo

  • Add changeset

1egoman added 7 commits April 27, 2026 16:04
…Start" packets being stored (fixes the last failing test)
- Use map insertion order instead of a timestamp for sorting
- Add comments
Also rename some fields which came up during writing the tests.
…es into the Depacketizer from the RemoteDataTrack
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 27, 2026

⚠️ No Changeset found

Latest commit: 64daceb

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@1egoman 1egoman requested a review from ladvoc April 27, 2026 21:28
@github-actions
Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
dist/livekit-client.esm.mjs 97.13 KB (+0.2% 🔺)
dist/livekit-client.umd.js 105.99 KB (+0.1% 🔺)

* The value applies to all current and future subscribers of this track. May be called
* before or after {@link RemoteDataTrack.subscribe}; live subscriptions pick up the new value
* immediately. Defaults to 1. */
setMaxPartialFrames(n: number): void {
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.

question: What are your thoughts on adding this to DataTrackSubscribeOptions instead? This would still have the caveat that "the value applies to all current and future subscribers of this track," but this is the case for bufferSize anyway. Also keeps API surface cleaner.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had brought up in our 1:1 that this needs to be configured at the track level, and not the subscription level, since there is one IncomingDataTrackPipeline per RemoteDataTrack. Given this, I'm curious what you have in mind here - are you suggesting this be changed so there's aIncomingDataTrackPipeline per subscription instead?

I will say that just generally, I am not really a big fan of this method approach, and would like to find a better place to put this, so if there's something I'm missing here I'm definitely open to changing this.

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.

I'm proposing putting it on DataTrackSubscribeOptions but this updates the track-level value under-the-hood. One disadvantage I can think of is there is no way to change max partial frames once you have a subscription (without obtaining a second one)—but not sure if this is something you would want to do anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm confused - if it was done this way, wouldn't that mean that if a user did .subscribe({ maxPartialFrames: 5 }) first, then .subscribe({ maxPartialFrames: 10 }) second, the last value would "win" and apply to both subscriptions since there is one pipeline for all subscriptions of a given track? The only way to work around this would be one pipeline per subscription rather than one pipeline per track?

Copy link
Copy Markdown
Contributor

@ladvoc ladvoc May 5, 2026

Choose a reason for hiding this comment

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

Yes, the latest value would win. This behavior would have to be documented at the option level similar to this disclaimer in Rust for buffer size.

);
});

it('should assemble multiple partial frames concurrently when maxPartialFrames is set', () => {
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.

praise: Nice test coverage!

Copy link
Copy Markdown
Contributor

@ladvoc ladvoc left a comment

Choose a reason for hiding this comment

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

Just the one question about exposing the new option, but looks good otherwise! I will port this to Rust so these can be merged at the same time.

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.

2 participants