Skip to content

Deploy of AdaptationStream leak fix - #37

Open
peaBerberian wants to merge 2 commits into
devfrom
fix/apap-stream-listener-leak
Open

Deploy of AdaptationStream leak fix#37
peaBerberian wants to merge 2 commits into
devfrom
fix/apap-stream-listener-leak

Conversation

@peaBerberian

Copy link
Copy Markdown
Owner

Deploy of canalplus#1781

@github-actions

Copy link
Copy Markdown

A built version of the branch has been deployed to the following URL:
https://github.com/peaBerberian/rx-player/releases/download/autobuild.abfe41a45958879cdd9984b83014d0a6311298a4/rx-player.tgz

You can import it by changing your package.json:

"rx-player": "https://github.com/peaBerberian/rx-player/releases/download/autobuild.abfe41a45958879cdd9984b83014d0a6311298a4/rx-player.tgz"

Then run:
npm install

The canalplus#1778 and canalplus#1779 issues / PR noticed a leak that seem to arise when
multiple quality switches happen.

I'm still unsure of the severity (looking at it what this fixes seems
very minimal, and we did not notice this yet on production at Canal+
including on low-memory devices for what seems to be a change that has
been here for 2 years - but external contributors actually did notice a
leak so maybe a set of conditions amplify the issue), but looking closely
at the code in question, there does seem to be an improper event listener
clean-up on a quality switch.

The issue is rooted in the complexity behind how quality switch happen:

- depending on heuristics, we may either perform an "urgent" quality
  switch (where we directly cancel the requests linked to the older
  quality) or a non-urgent one (where we will wait for the current
  requests to finish and only after load the new quality).

- If non-urgent, we want to still do the requests for the new quality as
  soon as we can, thus we parallelize it with the pushing operations of
  the segments we just loaded from the previous quality.

Thus when a "non-urgent" quality switch happen, there might be a short
time where several quality-linked modules are running at the same time
(the old one to push segments, the new one to load them), whereas at
first glance they seemed conflicting (one loads and push one quality,
the other loads and push another quality of the same thing).

This lead to an awkward architecture where the clean-up process of those
modules is subtly different than in other RxPlayer modules - this one
has actually 2 means to terminate:

- its `terminate` parameter, kind of like a SIGTERM: just finish what
  you're doing (e.g. finish loading segments and/or pushing them then
  stop).

  Once the `RepresentationStream` (the module in question) has finished
  loading segments, it sends a `terminating` event - but it might still
  be pushing segments.

  It however has no event to indicate that segments have been pushed,
  for now.

- its `cancelSignal` parameter, more akin to a SIGKILL: terminate
  everything now without delay.

  This one is e.g. triggered when stopping the content, changing the
  track etc.

The leaking event listener was wrongly linked to that "SIGKILL" signal,
even if it was intended to be cleaned up when the module is not needed
anymore. When the module was only "SIGTERMed", it was not cleaned up.

---

I chose to clean it up not right when "SIGTERMed", but when the module
itself anounced that it is "terminating" (it is done loading and is now
pushing segments).

I found it to be more appropriate for the logic in question and a
corresponding `CancellationSignal` was already used for other similar
logic linked to the same lifetime.
@peaBerberian
peaBerberian force-pushed the fix/apap-stream-listener-leak branch from 0797303 to 405b338 Compare January 19, 2026 13:55
@github-actions

Copy link
Copy Markdown

A built version of the branch has been deployed to the following URL:
https://github.com/peaBerberian/rx-player/releases/download/autobuild.a8898927222197f8c157a06e19320e007a0ae384/rx-player.tgz

You can import it by changing your package.json:

"rx-player": "https://github.com/peaBerberian/rx-player/releases/download/autobuild.a8898927222197f8c157a06e19320e007a0ae384/rx-player.tgz"

Then run:
npm install

@github-actions

Copy link
Copy Markdown

✅ Automated performance checks have passed on commit a8898927222197f8c157a06e19320e007a0ae384 with the base branch dev.

Details

Performance tests 1st run output

No significative change in performance for tests:

Name Mean Median
loading 21.17ms -> 21.34ms (-0.166ms, z: 1.67847) 30.00ms -> 30.00ms
seeking 14.17ms -> 14.28ms (-0.112ms, z: 1.88885) 12.30ms -> 12.30ms
audio-track-reload 28.50ms -> 28.78ms (-0.278ms, z: 1.47949) 41.85ms -> 42.00ms
cold loading multithread 48.11ms -> 47.35ms (0.760ms, z: 10.78014) 70.80ms -> 69.60ms
seeking multithread 79.28ms -> 76.69ms (2.587ms, z: 0.86316) 10.80ms -> 10.80ms
audio-track-reload multithread 27.92ms -> 27.93ms (-0.011ms, z: 0.48073) 41.40ms -> 41.25ms
hot loading multithread 15.88ms -> 15.68ms (0.194ms, z: 5.39399) 23.40ms -> 22.95ms

@github-actions

Copy link
Copy Markdown

A built version of the branch has been deployed to the following URL:
https://github.com/peaBerberian/rx-player/releases/download/autobuild.eb574a3a7288ebe348ecc39e4fbcdfa8ac7c175b/rx-player.tgz

You can import it by changing your package.json:

"rx-player": "https://github.com/peaBerberian/rx-player/releases/download/autobuild.eb574a3a7288ebe348ecc39e4fbcdfa8ac7c175b/rx-player.tgz"

Then run:
npm install

@github-actions

Copy link
Copy Markdown

✅ Automated performance checks have passed on commit eb574a3a7288ebe348ecc39e4fbcdfa8ac7c175b with the base branch dev.

Details

Performance tests 1st run output

No significative change in performance for tests:

Name Mean Median
loading 21.89ms -> 22.17ms (-0.277ms, z: 0.01311) 31.05ms -> 30.90ms
seeking 12.51ms -> 10.42ms (2.094ms, z: 1.99431) 12.60ms -> 12.60ms
audio-track-reload 29.70ms -> 29.53ms (0.168ms, z: 0.93963) 43.50ms -> 43.35ms
cold loading multithread 49.56ms -> 48.58ms (0.983ms, z: 9.85602) 72.80ms -> 71.55ms
seeking multithread 98.93ms -> 79.56ms (19.371ms, z: 0.43712) 10.95ms -> 10.95ms
audio-track-reload multithread 28.97ms -> 28.79ms (0.176ms, z: 2.27073) 42.75ms -> 42.60ms
hot loading multithread 16.74ms -> 16.53ms (0.211ms, z: 3.98733) 24.45ms -> 24.30ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant