Skip to content

fix(rum): keep reporting events while the host has no session - #20

Closed
Fiona2016 wants to merge 1 commit into
publishfrom
fix/host-session-gap-stops-replay-not-rum
Closed

fix(rum): keep reporting events while the host has no session#20
Fiona2016 wants to merge 1 commit into
publishfrom
fix/host-session-gap-stops-replay-not-rum

Conversation

@Fiona2016

Copy link
Copy Markdown
Collaborator

The deadlock

0.0.7 made this page report no tracked session while the host says it has none. That is too broad: it also stops the events the host needs to notice the user is still there.

fc-sdk-electron renews its session from exactly one thing — a click action forwarded over the bridge:

renderer click → browser-rum → BridgeHandler → UserActivityTracker
    → END_USER_ACTIVITY → SessionManager renews

So the host waits for a click to renew, and this page refuses to report the click because the host has no session. Once the session expires it never comes back, and the application goes quiet until it is restarted.

Caught by the fc-sdk-electron e2e suite. Four session-renewal cases pass on 0.0.6 and fail on 0.0.7; the second event after a renewal arrives with no session id at all, because the renewal never happened.

The fix

The two kinds of data this page produces do not carry the same risk, and are no longer treated the same:

goes through the host? session id while the host has none
RUM events yes — host overrides session.id never reaches the intake keep flowing
Replay segments no — uploaded directly reaches the intake as-is stop recording

So findTrackedSession() keeps returning a session, named with the placeholder the host overrides, and turns sessionReplay OFF instead. canStartRecording treats SessionReplayState.OFF exactly like no session, so nothing is recorded and no segment is uploaded.

Two things that made this safe to narrow, both checked rather than assumed:

  • SESSION_EXPIRED has only two subscribers — trackViews ends the current view, postStartStrategy stops the recorder and re-arms it for SESSION_RENEWED. Neither stops action or error collection, so the click survives.
  • UserActivityTracker on the host side sits on the raw event, before assembly. Even if the host discards the event for having no session of its own, the activity signal still fires.

The id the host held a moment ago is still never reused — it belongs to a session that has ended.

Verified

  • browser-sdk unit: 2684 pass
  • fc-sdk-electron e2e against a build of this branch: the four failing cases go green, 39/39 pass

Reporting no tracked session at all during the gap was too broad, and it
deadlocks a host that renews its session from what this page reports.

`fc-sdk-electron` does exactly that: the only thing that renews its session
is a click action forwarded over the bridge. Stopping collection while it has
no session means the click never arrives, so the session that was only meant
to be paused is never renewed — the host goes quiet for good, and only a
restart brings it back.

The two kinds of data this page produces do not carry the same risk, so they
are no longer treated the same. Events reach the intake through the host,
which overrides their session id, so the placeholder never gets there and
they can keep flowing. Session Replay segments bypass the host entirely,
nothing overrides them, and the placeholder is a constant every application
shares — so recording is what stops, and `SESSION_EXPIRED` still makes the
recorder flush rather than hold a segment open across the gap.

The id the host held a moment ago is still never reused: it belongs to a
session that has ended.
@Fiona2016

Copy link
Copy Markdown
Collaborator Author

Superseded by fixing this on the host side instead.

The deadlock is real, but this was the wrong end of it. fc-sdk-electron renewing its session from an event stream that this page stops during the gap is a cycle, and the fix belongs where the cycle is: the host gets its own activity source, from webContents input events, independent of what the page reports.

That is strictly broader than what this branch restores — it covers keyboard as well as clicks, works on windows with no Browser SDK at all, and does not depend on the renderer having trackUserInteractions enabled, which the current signal silently does.

Meanwhile the behaviour this branch changes is defensible on its own: with no session to attribute anything to, the page has nothing worth sending — the host discards those events at assembly anyway. Keeping them flowing would only serialize and ship data that dies on arrival.

Branch left in place in case the host-side fix turns out not to cover something.

@Fiona2016 Fiona2016 closed this Aug 7, 2026
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