Skip to content

🐛 fix resource timing buffer listener not stopped on cleanup#4360

Open
thomas-lebeau wants to merge 1 commit intomainfrom
thomas.lebeau/fix-resource-timing-buffer-listener-cleanup
Open

🐛 fix resource timing buffer listener not stopped on cleanup#4360
thomas-lebeau wants to merge 1 commit intomainfrom
thomas.lebeau/fix-resource-timing-buffer-listener-cleanup

Conversation

@thomas-lebeau
Copy link
Collaborator

@thomas-lebeau thomas-lebeau commented Mar 20, 2026

Motivation

The manageResourceTimingBufferFull function registers a listener for the resourcetimingbufferfull event on the performance object. However, the return value (a cleanup function) was not being captured or called when the PerformanceObservable was cleaned up, causing the listener to remain active after the observer was disconnected.

ERROR LOG: 'Datadog Browser SDK:', 'Leaked listener
  event names: "resourcetimingbufferfull"
  attached with: "longTaskCollection when browser only supports legacy longtask should collect when trackLongTasks=true"
  executed outside of a spec
  attachment stack: Error
    at withLeakDetection (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:101294:53)
    at EventTarget.addEventListener (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:101264:55)
    at http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:12854:16
    at Array.forEach (<anonymous>)
    at addEventListeners (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:12851:14)
    at addEventListener (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:12802:10)
    at manageResourceTimingBufferFull (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:130856:111)
    at Observable.onFirstSubscribe (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:130813:5)
    at Observable.addObserver (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:59876:66)
    at Observable.subscribe (http://localhost:9876/absolute/tmp/_karma_webpack_163552/commons.js?24aece18a060ffd3181f9013588a77285834b230:59849:10)'

Additionally, resourceTimingBufferFullListener was typed as non-nullable, which prevented proper cleanup and reset of the module-level variable.

Changes

  • Capture the return value of manageResourceTimingBufferFull and call it in the cleanup callback of createPerformanceObservable
  • Reset resourceTimingBufferFullListener to undefined after stopping it, so subsequent calls can re-register the listener if needed
  • Fix the type of resourceTimingBufferFullListener to | undefined to reflect its actual nullable state

Test instructions

  1. Initialize the RUM SDK
  2. Stop the SDK (triggering cleanup)
  3. Verify no lingering resourcetimingbufferfull event listeners remain on the performance object

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

- Call stopManageResourceTimingBufferFull() in the observable teardown
- Reset resourceTimingBufferFullListener to undefined after stopping to avoid stale references
- Type the module-level variable as optional (| undefined) to reflect its possible absent state
@thomas-lebeau thomas-lebeau marked this pull request as ready for review March 20, 2026 10:14
@thomas-lebeau thomas-lebeau requested a review from a team as a code owner March 20, 2026 10:14
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13ebe8cc40

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


return () => {
observer.disconnect()
stopManageResourceTimingBufferFull()

Choose a reason for hiding this comment

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

P1 Badge Keep shared resource buffer listener alive across observables

Calling stopManageResourceTimingBufferFull() in every createPerformanceObservable cleanup removes the single module-level resourcetimingbufferfull listener even when other performance observables are still subscribed. This is reachable with short-lived subscriptions like createPageActivityObservable (unsubscribed when waitPageActivityEnd completes), while long-lived resource collection remains active, so the resource timing buffer is no longer cleared and later resource entries can be dropped once full. The cleanup needs ref-counting (or equivalent) so the shared listener is only removed when the last dependent observable stops.

Useful? React with 👍 / 👎.

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.

1 participant