Skip to content

♻️ Async session manager#4131

Open
thomas-lebeau wants to merge 43 commits intov7from
thomas.lebeau/asyc-session-manager-with-telemetry-merge-main
Open

♻️ Async session manager#4131
thomas-lebeau wants to merge 43 commits intov7from
thomas.lebeau/asyc-session-manager-with-telemetry-merge-main

Conversation

@thomas-lebeau
Copy link
Collaborator

@thomas-lebeau thomas-lebeau commented Jan 29, 2026

Motivation

Important

Base branch for merging is v7

Prepare for the upcoming new session manager that will use modern async APIs such as the native Lock API and CookieStore API. These APIs are inherently asynchronous, so the session manager initialization needs to be async to support them.

Also ensure telemetry respects user consent by deferring initialization until consent is granted.

Changes

  • Async session manager: Session manager now starts asynchronously via callback pattern for both RUM and Logs
  • Telemetry consent: Telemetry initialization is deferred until tracking consent is granted in onGrantedOnce
  • Test improvements: Update tests to handle async session manager initialization using collectAsyncCalls
  • Documentation: Add async testing best practices to AGENTS.md

Test instructions

  1. Run unit tests: yarn test:unit
  2. Run E2E tests: yarn test:e2e
  3. Verify session creation works correctly with different consent states

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

BenoitZugmeyer and others added 30 commits January 16, 2026 15:56
rum-events-format was unexpectedly updated. This commit reverts the
submodule and generated files to the main branch.
This commit makes it easier to change large functions signatures like
`makeRumPublicApi`, `makePreStartRum`, etc.
No need to start the telemetry again in `startLogs` and `startRum`.
thomas-lebeau and others added 6 commits January 28, 2026 16:02
Replace polling-based waitFor with the cleaner collectAsyncCalls pattern
which waits for a specific number of spy calls and fails fast on extra calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@thomas-lebeau thomas-lebeau requested a review from a team as a code owner January 29, 2026 12:30
@thomas-lebeau thomas-lebeau changed the title ♻️ Async session manager with telemetry improvements ♻️ Async session manager Jan 29, 2026
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: fc052aa79e

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

Comment on lines +92 to +96
trackingConsentState.observable.subscribe(() => {
if (trackingConsentState.isGranted()) {
sessionStore.expandOrRenewSession()
} else {
sessionStore.expire(false)

Choose a reason for hiding this comment

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

P1 Badge Subscribe to consent changes before async init

The consent change handler is registered only inside the expandOrRenewSession callback. If the session store is locked (e.g., Chromium cookie locking) and that callback is delayed, a trackingConsentState.update(NOT_GRANTED) during that window will be missed, so sessionStore.expire(false) never runs and the session can stay active despite revoked consent. This is a regression from the previous synchronous subscription and can leak data in the lock-wait scenario.

Useful? React with 👍 / 👎.

@datadog-official
Copy link

datadog-official bot commented Jan 29, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage
Patch Coverage: 81.00%
Overall Coverage: 77.27% (+0.02%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1183c6f | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@thomas-lebeau thomas-lebeau marked this pull request as draft January 29, 2026 12:56
@cit-pr-commenter-54b7da
Copy link

cit-pr-commenter-54b7da bot commented Jan 29, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 167.98 KiB 168.27 KiB +299 B +0.17%
Rum Profiler 4.32 KiB 4.32 KiB 0 B 0.00%
Rum Recorder 24.54 KiB 24.54 KiB 0 B 0.00%
Logs 56.25 KiB 56.47 KiB +230 B +0.40%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 124.88 KiB 125.15 KiB +279 B +0.22%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.0038 0.0043 +13.16%
RUM - add action 0.0121 0.0139 +14.88%
RUM - add error 0.012 0.0128 +6.67%
RUM - add timing 0.0024 0.0031 +29.17%
RUM - start view 0.003 0.0033 +10.00%
RUM - start/stop session replay recording 0.0006 0.0007 +16.67%
Logs - log message 0.0138 0.016 +15.94%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
RUM - add global context 27.52 KiB 28.80 KiB +1.27 KiB
RUM - add action 52.53 KiB 54.75 KiB +2.22 KiB
RUM - add timing 26.99 KiB 27.90 KiB +938 B
RUM - add error 57.79 KiB 58.70 KiB +923 B
RUM - start/stop session replay recording 26.73 KiB 26.69 KiB -41 B
RUM - start view 428.92 KiB 429.60 KiB +692 B
Logs - log message 47.48 KiB 49.86 KiB +2.38 KiB

🔗 RealWorld

If consent is revoked while waiting for the session store lock (e.g., Chromium
cookie locking), the session should be expired instead of proceeding with
initialization. This prevents a race condition where consent revocation during
the lock-wait period would be missed.
@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/asyc-session-manager-with-telemetry-merge-main branch from 37c3f07 to 3b4ec11 Compare January 29, 2026 15:16
@thomas-lebeau thomas-lebeau changed the base branch from main to v7 January 29, 2026 15:44
@thomas-lebeau thomas-lebeau marked this pull request as ready for review January 29, 2026 15:45
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: 3b4ec110a4

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

Comment on lines +188 to +190
startRumSessionManager(configuration, trackingConsentState, (newSessionManager) => {
sessionManager = newSessionManager
tryStartRum()

Choose a reason for hiding this comment

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

P1 Badge Guard async RUM start against revoked consent

Because startRumSessionManager is now async, the onGrantedOnce callback can run while consent is granted, but the session manager can become ready later (e.g., cookie lock delay). If consent is revoked during that window, this callback still calls tryStartRum() once the manager resolves, and tryStartRum doesn’t re-check consent, so RUM can start and collect despite NOT_GRANTED. Consider checking trackingConsentState.isGranted() before calling tryStartRum() (or cancelling the pending start on revoke) to avoid starting RUM after a mid-init revoke.

Useful? React with 👍 / 👎.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed by hoisting startTrackingConsentContext (which discard telemetry using hooks if consent is not granted)

Comment on lines +113 to +115
startLogsSessionManager(configuration, trackingConsentState, (newSessionManager) => {
sessionManager = newSessionManager
tryStartLogs()

Choose a reason for hiding this comment

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

P1 Badge Avoid starting Logs after consent revoked during async init

The async startLogsSessionManager callback unconditionally calls tryStartLogs() once the session manager resolves. If consent is granted at init but revoked before the session manager is ready (e.g., cookie lock delay), this path still starts Logs even though consent is currently not granted, because tryStartLogs doesn’t re-check consent. Add a consent check (or cancel the pending start on revoke) before calling tryStartLogs() to prevent starting Logs in a revoked-consent state.

Useful? React with 👍 / 👎.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ditto

Tests in 'buffers API calls before starting RUM' section expected
synchronous doStartRum calls but session manager initialization is
now async. Added proper async/await with collectAsyncCalls to wait
for the async callbacks.

Fixes race conditions on slower browsers (Chrome 63, Edge 80, Firefox 67).
Tests in 'trackViews mode' section expected synchronous or partially
async doStartRum calls but session manager initialization is now fully
async. Added proper async/await with collectAsyncCalls to wait for all
async callbacks to complete.

Fixes race conditions on slower browsers (Edge 80).
Introduced a new function to reset buffered and ongoing session store operations, ensuring a clean state when stopping the session manager. This change enhances session management  unt test reliability.
Move startTrackingConsentContext from startRum to preStartRum to align
with the pattern of initializing consent-dependent contexts earlier in
the startup sequence. This removes the trackingConsentState parameter
from startRum since it's no longer needed there.
Move startTrackingConsentContext from startLogs to preStartLogs to align
with the pattern of initializing consent-dependent contexts earlier in
the startup sequence. This removes the trackingConsentState parameter
from startLogs since it's no longer needed there.
@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/asyc-session-manager-with-telemetry-merge-main branch from 411583d to 1183c6f Compare February 3, 2026 11:02
})
})

describe('tracking consent', () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved to an e2e test

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