Skip to content

Browser client starts a new session every time the tab becomes visible #207

Open

Description

@ejsmith

With sessions enabled in @exceptionless/browser 3.2.1 (and everything built on it: @exceptionless/vue, @exceptionless/react, @exceptionless/angularjs), BrowserLifeCyclePlugin calls client.startup() on every visibilitychange to visible, and startup() always submits a session start. Each time a user switches back to the tab, a session start event is sent, even though the session never ended or timed out.

Where

What happens

  • With useSessions(true, 60000, true) (client-managed session ids), every hide/show cycle submits a session start with a new reference_id. The previous session is never ended, so it stays open on the server until it is closed as inactive, and one visit gets split into many sessions.
  • With the default identity-based sessions, a session start event is still sent on every tab switch. The server discards it while the user's session is open, but it is still an extra request and event for each tab switch.

Repro output (jsdom, @exceptionless/browser 3.2.1, useSessions(true, 60000, true), three hide/show cycles):

after startup, session starts: 1
after 3 hide/show cycles (~150ms), session starts: 4 [ '89e0...', 'e72b...', '43a9...', 'ac70...' ]

Expected

Becoming visible again resumes the current session: it restarts heartbeats and queue processing without submitting a session start. A new session should start only if the previous one ended or the tab was hidden for longer than the session timeout.

Steps to reproduce

  1. Exceptionless.startup((c) => { c.apiKey = "..."; c.useSessions(true, 60000, true); }) in a page.
  2. Switch to another tab and back a few times.
  3. Watch the network tab or a plugin that records type === "session" events: each return to the tab submits a new session start.

Suggested fix

Split resume from startup. On visible, resume timers and the queue (or call startup() with session start suppressed), and submit a session start only if there's no current session or the time since the last activity exceeds a session timeout. The React Native web listener (ReactNativeLifeCyclePlugin.setupWebListeners) has the same visibility pattern and should get the same change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions