Skip to content

🐛 await re-grant if consent is revoked during session manager init#4605

Draft
thomas-lebeau wants to merge 1 commit into
v7from
thomas.lebeau/fix-session-manager-consent-race
Draft

🐛 await re-grant if consent is revoked during session manager init#4605
thomas-lebeau wants to merge 1 commit into
v7from
thomas.lebeau/fix-session-manager-consent-race

Conversation

@thomas-lebeau
Copy link
Copy Markdown
Collaborator

Motivation

Addresses a P2 review comment on #4425.

When tracking consent is revoked while startSessionManager is awaiting the cookie lock / Cookie Store call (the "async initialization" window), the previous code called expire() and resolved with undefined. The RUM and Logs pre-start strategies (preStartRum.ts:180, preStartLogs.ts:109) invoke startSessionManager from trackingConsentState.onGrantedOnce, which fires exactly once and then unsubscribes (trackingConsent.ts:30-41). As a result, a customer who re-granted consent later in the same page could never bring the SDK back — the session manager was permanently stuck in pre-start state.

Changes

  • packages/core/src/domain/session/sessionManager.ts: replace the early-return-on-revoked-consent branch with a wait loop. When consent isn't granted at the end of the async init, wait for the next grant via onGrantedOnce and re-resolve the initial state before installing the manager (intervening state changes in other tabs are picked up by the re-resolve). If the manager is stopped while waiting, exit cleanly.
  • packages/core/src/domain/session/sessionManager.spec.ts:
    • Replace the previous "resolves with undefined on revocation during init" test (which codified the old behavior) with one verifying the promise stays pending while consent stays revoked.
    • Add a test verifying the manager does install once consent is granted again after being revoked mid-init.
    • Add a flushMicrotasks helper (10 cycles) so chained awaits — setSessionState resolution, the .catch(monitorError) chain, and the post-await continuation — all run before assertions.

Test instructions

  • yarn test:unit --spec packages/core/src/domain/session/sessionManager.spec.ts — the two new tests under tracking consent pass. Reverting sessionManager.ts makes both fail (one because the promise resolves with undefined too early, the other because the manager never installs after re-grant).
  • yarn test:unit — full suite stays green (3534 tests).
  • yarn typecheck / yarn lint clean.

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

If tracking consent is revoked while startSessionManager is waiting on the
cookie lock / Cookie Store call, the previous code resolved with undefined.
RUM and Logs pre-start strategies invoke startSessionManager from
trackingConsentState.onGrantedOnce, which fires exactly once and then
unsubscribes — so a later re-grant in the same page could never bring the
SDK back. The session manager was permanently stuck in pre-start state.

Replace the early return with a wait loop: when consent isn't granted at
the end of the async init, wait for the next grant (via onGrantedOnce) and
re-resolve the initial state before installing the manager. Intervening
state changes in other tabs are picked up by the re-resolve.

Tests cover both the wait (promise stays pending while consent stays
revoked) and the recovery (promise resolves to a working manager once
consent is granted again).
@datadog-datadog-prod-us1
Copy link
Copy Markdown

datadog-datadog-prod-us1 Bot commented May 11, 2026

Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 75.00%
Overall Coverage: 77.49% (+0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a559fc7 | Docs | Datadog PR Page | Give us feedback!

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 11, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 169.26 KiB 169.35 KiB +95 B +0.05%
Rum Profiler 5.97 KiB 5.97 KiB 0 B 0.00%
Rum Recorder 21.23 KiB 21.23 KiB 0 B 0.00%
Logs 54.56 KiB 54.65 KiB +92 B +0.16%
Rum Slim 127.59 KiB 127.68 KiB +92 B +0.07%
Worker 22.99 KiB 22.99 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.0018 0.0108 +500.00%
RUM - add action 0.0112 0.0428 +282.14%
RUM - add error 0.0102 0.0748 +633.33%
RUM - add timing 0.0005 0.0025 +400.00%
RUM - start view 0.0101 0.0502 +397.03%
RUM - start/stop session replay recording 0.0007 0.0035 +400.00%
Logs - log message 0.0172 0.0529 +207.56%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
RUM - add global context 38.90 KiB 38.63 KiB -278 B
RUM - add action 62.40 KiB 63.13 KiB +746 B
RUM - add timing 37.14 KiB 46.37 KiB +9.23 KiB
RUM - add error 67.68 KiB 70.92 KiB +3.24 KiB
RUM - start/stop session replay recording 41.66 KiB 41.27 KiB -394 B
RUM - start view 484.99 KiB 466.83 KiB -18.16 KiB
Logs - log message 54.21 KiB 54.21 KiB +7 B

🔗 RealWorld

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