Skip to content

♻️ Make session manager injectable and isolate for v7 rewrite#4157

Open
thomas-lebeau wants to merge 5 commits intov7from
thomas.lebeau/v7-session-manager-from-scratch-clean
Open

♻️ Make session manager injectable and isolate for v7 rewrite#4157
thomas-lebeau wants to merge 5 commits intov7from
thomas.lebeau/v7-session-manager-from-scratch-clean

Conversation

@thomas-lebeau
Copy link
Collaborator

@thomas-lebeau thomas-lebeau commented Feb 10, 2026

Motivation

Prepare the session manager layer for a from-scratch rewrite in v7. The existing session manager internals (cookies, storage, core session store) are tightly coupled to boot-level tests, making it hard to replace the implementation without breaking unrelated tests.

This PR decouples all non-session-manager code from session internals, so the session manager can be rewritten in isolation.

Changes

1. Injectable session manager factory

Move the stub-vs-real session manager branching from createPreStartStrategy to the caller (rumPublicApi / logsPublicApi) via a factory parameter:

graph LR
    A[rumPublicApi / logsPublicApi] -->|ternary: bridge ? stub : real| B[factory]
    B -->|passed as param| C[createPreStartStrategy]
    C -->|calls factory| D[session manager instance]
Loading
  • BREAKING CHANGE: When no storage strategy is available (cookies/localStorage unavailable), neither SDK will send data. Previously Logs would still start without storage — now it requires explicit sessionPersistence: 'memory' to work without storage. In worker environments, Logs uses the real session manager with memory persistence (we can revisit that when we star using CookieStore as this seems supported in service workers). RUM is explicitly blocked with a warning.
  • createPreStartStrategy receives one factory, just calls it — no branching logic
  • Callers use: canUseEventBridge() ? stub : real

2. Prove isolation via gut-then-restore

To verify that all non-session-manager tests use mocks (not real implementations), the session manager bodies were temporarily gutted and their unit tests skipped (xdescribe). All 3071 remaining tests passed with zero failures, proving the isolation is complete. The implementations and tests were then fully restored.

3. Mock infrastructure

  • Boot tests (preStartRum.spec, preStartLogs.spec) inject mock factories — no more stopSessionManager() cleanup or cookie manipulation
  • Public API tests (rumPublicApi.spec, logsPublicApi.spec) inject mock session managers via optional parameter on makeRumPublicApi / makeLogsPublicApi
  • mockRumSessionManager / mockLogsSessionManager updated with factory wrappers

4. Worker environment support

Use a defense-in-depth strategy for worker environments, handling workers at multiple layers:

  • Storage layer: selectSessionStoreStrategyType forces SessionPersistence.MEMORY in workers — cookies and localStorage are unavailable in worker contexts
  • Session manager: Skip DOM event tracking (trackActivity, trackVisibility, trackResume) in workers — no DOM events to listen to
  • RUM: Block entirely in preStartRum with an explicit warning — RUM features (DOM observation, user interactions) are not applicable in workers
  • Logs: Uses the real session manager (not a stub) — the storage and session manager layers handle the worker context, so Logs works normally with memory-backed sessions

New exports from @datadog/browser-core: selectSessionStoreStrategyType, SessionStoreStrategyType
startSessionManager now takes sessionStoreStrategyType as a direct parameter.

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

@cit-pr-commenter-54b7da
Copy link

cit-pr-commenter-54b7da bot commented Feb 10, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 169.73 KiB 169.84 KiB +110 B +0.06%
Rum Profiler 4.29 KiB 4.29 KiB 0 B 0.00%
Rum Recorder 24.61 KiB 24.61 KiB 0 B 0.00%
Logs 56.95 KiB 56.90 KiB -57 B -0.10%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 126.56 KiB 126.66 KiB +105 B +0.08%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance

Pending...

🧠 Memory Performance

Pending...

🔗 RealWorld

@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Feb 10, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 76.92%
Overall Coverage: 77.26%

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

@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/v7-session-manager-from-scratch-clean branch from 7ccc7fc to c6ccf8d Compare February 11, 2026 09:37
Move the stub-vs-real session manager branching from createPreStartStrategy to the caller (rumPublicApi/logsPublicApi) via a factory parameter. This decouples boot-level tests from session internals (cookies, storage).

- Unify stub signatures to callback pattern (config, consent, onReady)
- Accept startSessionManagerImpl in createPreStartStrategy
- Callers use ternary: canUseEventBridge() ? stub : real
- Boot tests inject mock factories, removing stopSessionManager cleanup
Gut the real session manager implementations (core, rum, logs) and skip their unit tests. This ensures all non-session-manager tests use mocks, isolating the session manager work for the upcoming rewrite.
The gutting confirmed all non-session-manager tests use mocks. Now restore the real implementations so the full test suite passes (3174 tests, 0 failures).
@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/v7-session-manager-from-scratch-clean branch from c6ccf8d to b9b9897 Compare February 13, 2026 10:49
…iguration

Move the isWorkerEnvironment check from configuration (sessionStoreStrategyType) to the public APIs, using session manager stubs in worker environments.
  This allows the Logs SDK to load in worker environments by aligning worker handling with the event bridge pattern.
- Force memory persistence at the storage level for workers
- Block RUM entirely in workers with explicit warning
- Let Logs use the real session manager (storage handles memory)
- Skip DOM event tracking in session manager for workers
@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/v7-session-manager-from-scratch-clean branch from b9b9897 to e356ec1 Compare February 13, 2026 17:02
@thomas-lebeau thomas-lebeau marked this pull request as ready for review February 13, 2026 17:03
@thomas-lebeau thomas-lebeau requested a review from a team as a code owner February 13, 2026 17:03
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: e356ec178a

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

onReady: (sessionManager: LogsSessionManager) => void
): void {
onReady({
findTrackedSession: () => ({}),

Choose a reason for hiding this comment

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

P1 Badge Honor sessionSampleRate in bridge session stub

The bridge stub now always reports a tracked session via findTrackedSession: () => ({}), so Logs events are never discarded by startSessionContext even when sessionSampleRate is 0. Before this change, the stub used sampling logic and could return undefined for non-tracked sessions. In event-bridge/WebView integrations, this regresses sampling behavior and will forward logs that should be dropped.

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.

Good catch. Sampling decision should be handled by the other side of bridge (i.e. the mobile SDK), similarly than RUM

})
} else {
sessionManager = startLogsSessionManagerStub(configuration)
startLogsSessionManagerImpl(configuration, trackingConsentState, (newSessionManager) => {

Choose a reason for hiding this comment

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

P2 Badge Guard session manager start when no storage strategy exists

This path now always starts the logs session manager after consent, but configuration.sessionStoreStrategyType can still be undefined when cookies/localStorage are unavailable. In that case startSessionManager later dereferences configuration.sessionStoreStrategyType! and throws before tryStartLogs() can run, so initialization fails through a monitored exception instead of a controlled no-session behavior.

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