Skip to content

Fix some data track subscription edge cases#1892

Open
1egoman wants to merge 8 commits intomainfrom
data-track-subscription-edge-cases
Open

Fix some data track subscription edge cases#1892
1egoman wants to merge 8 commits intomainfrom
data-track-subscription-edge-cases

Conversation

@1egoman
Copy link
Copy Markdown
Contributor

@1egoman 1egoman commented Apr 16, 2026

A customer surfaced some issues with the signal parameter passed to data track subscriptions - when this was passed and aborted during certain parts of the subscription / participant connection lifecycle outside the happy path, it was possible that things could get into an inconsistent state:

  • Aborting after participant disconnect - the stream would throw a Cannot close an errored readable stream error in this case because the manager tried to clean up a subscription that the user had already manually aborted. So, make sure the stream controller gets removed from the list so it doesn't get double-closed.

  • The data track is unpublished during the brief window of time between the sfu subscription being established and the readable stream finishing being setup. If this happened, the readable stream would hang forever isntead of explicitly aborting.

  • Abort signal listener not being cleaned up properly in all cases - if the manager closes the stream (the stream doesn't get into an error state, it is explicitly closed), then this wouldn't clean up the abort signal listener, so if a user triggered the abort signal later, it would cause an error to be throw.

These cases now all have explicit tests that test a few variations to ensure that this doesn't regress.

1egoman added 5 commits April 15, 2026 16:42
This logic was not being called on stream abort, which meant that you
would unintentionally "leak" data stream subscriptions by aborting
…ined cases

When a participant disconnects, this should work fine if the
subscription has already been aborted
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 16, 2026

🦋 Changeset detected

Latest commit: 49748e0

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 16, 2026

size-limit report 📦

Path Size
dist/livekit-client.esm.mjs 95.81 KB (+0.15% 🔺)
dist/livekit-client.umd.js 104.73 KB (+0.02% 🔺)

1egoman added 3 commits April 16, 2026 12:09
…onStream

subscribeRequest is no longer called directly within RemoteDataTrack, so
the tests now match more closely how logically this works now
@1egoman 1egoman marked this pull request as ready for review April 16, 2026 16:19
}
const currentDescriptor = this.descriptors.get(sid);
if (currentDescriptor?.subscription.type === 'active') {
currentDescriptor.subscription.streamControllers.delete(streamController);
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 think cleanup() is also trying to clean up the streamController, should we move the code to one place instead?
like having cleanup() does the cleaning, and onAbort() handles the signaling and cleanup

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.

Ah, good point - this is I think duplicative. I will remove this and let the copy in cleanup handle deleting the stream controller from the map instead. 👍

currentDescriptor.subscription.streamControllers.delete(streamController);
}

streamController.error(DataTrackSubscribeError.cancelled());
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.

onAbort() is called after abort(), does streamController guarantee that it is not closed yet ?

and will it throw if streamController is closed already ?

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 think it should be ok, the mdn docs for the error method explicitly say that it can be called multiple times.

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.

3 participants