Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

What is a session? #38

Closed
billyvg opened this issue Mar 30, 2022 · 7 comments
Closed

What is a session? #38

billyvg opened this issue Mar 30, 2022 · 7 comments
Labels
question Further information is requested

Comments

@billyvg
Copy link
Member

billyvg commented Mar 30, 2022

What should we consider as a session? Things to consider:

  • Refreshing the current tab
  • Navigating to an external site
  • Opening a new tab to current app
  • non-SPAs
  • User goes idle/inactive
  • User changes tabs or hides browser
  • User changes tabs and goes back to app
  • Usage of cookies/localStorage
@billyvg billyvg added the question Further information is requested label Mar 30, 2022
@billyvg billyvg added this to the v0 - Internal Sentry Release milestone Mar 30, 2022
@billyvg
Copy link
Member Author

billyvg commented Mar 30, 2022

  • Usage of cookies/localStorage

We should speak with the SDK team (regarding this comment: #13 (comment)) - I don't think the issue of having this live in the main SDK repo should be a factor in how we design for a session. In order to provide the best UX, we'll need to use cookies. Hopefully, this isn't an issue because the plugin is opt-in.

Cookies are required if we want to the below to be considered in a single session)

  1. support non-SPAs (e.g. link navigation)
  2. page refreshes
  3. opening current app in new tab
  • User goes idle/inactive

The session should probably have an inactivity timeout. e.g. if user loads app and then leaves their computer for minutes for lunch. That should be considered a single session. If they come back and interact again, it should create a new session.

  • User changes tabs or hides browser, and then later goes back to app

We should allow a grace period for the user to leave the tab and then come back.

Exact numbers aren't needed for the above points, as they can be tweaked later.

@ryan953
Copy link
Member

ryan953 commented Mar 31, 2022

We should build up a flow-chart for sessions

graph TD;
    onUserAction(on user activity);
    onFullPageLoad(Full Page Load);
    onClick(Click - document capture phase);
    onScroll(Scroll - document);
    onKeyPress(Keypress - document capture phase);
    onPageActive(Page active - switch browser tabs or alt-tab);

    hasCookie{Existing Cookie?};
    createCookie[/cookies.set new Replay/];
    hasIdleTimeout{Has idle timeout?};
    setTimeout[/create Idle timeout/];
    endSess([End Session]);
    
    #onUserAction-->hasCookie;
    onUserAction-->onFullPageLoad-->hasCookie;
    onUserAction-->onClick-->hasCookie;
    onUserAction-->onScroll-->hasCookie;
    onUserAction-->onKeyPress-->hasCookie;
    onUserAction-->onPageActive-->hasCookie;

    hasCookie-- yes -->hasIdleTimeout;
    hasCookie-- no -->createCookie; 
    
    createCookie-->hasIdleTimeout;

    hasIdleTimeout-- yes --> wait;
    hasIdleTimeout-- no --> setTimeout;

    setTimeout-->wait;

    wait-- triggered --> endSess;
    wait-- event --> onUserAction;
Loading

Some simple conditions like this could mean that async activity happening in the background of a stale tab won't get captured after the idle timeout has triggered.

@ryan953
Copy link
Member

ryan953 commented Apr 1, 2022

I think we should look at sessionStorage to start: so that rrweb events are isolated to one tab and there is a single stream of rrweb events being applied to the base snapshot.

If we just have cookies and/or localStorage here are some reproduction steps that I think would cause a problem for the viewer later on:

timestamp action outcome parent
0 Tab A navigates to /home snapshot created -
1 Navigate B to /about in new tab rrweb event parent=0
2 Click something on /about rrweb event parent=1
3 Switch to view Tab A - -
4 Navigate to /contact rrweb event parent=0

It's like a git branch where we endup with two HEADs and cannot merge them:

  • at time=2 the timeline contains three steps: /home snapshot + navigate to /about + click
  • at time=4 the timeline has only two steps: /home snapshot + navigate to /contact

In this case it would be better to show two rrweb-players.

The downsides of sessionStorage for v0 are small. We lose the "resume replay if tab is closed and then re-opened", maybe others.
https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

But with a combination of both sessionStorage and localStorage/cookies we could solve that "re-opened a tab" problem down the line.

@JoshFerge
Copy link
Member

related to your above @ryan953, here's what i just drew regarding the sdk's communication with the backend (relay). Let me know if i'm missing details, or feel free to just edit it.

sequenceDiagram
    participant User
    participant SentryReplaySDK
    participant Relay

    User->>+User: Lands on Webpage
    par SentryReplaySDK to Relay
        SentryReplaySDK->>+Relay: Send replay.event Init 
        SentryReplaySDK->>+Relay: Send replay.rrweb attachment 
    end
    User->>+User: Navigates, clicks stuff, etc.

    loop every 15 seconds
        par SentryReplaySDK to Relay
        SentryReplaySDK->>+Relay: Send replay.event update 
        SentryReplaySDK->>+Relay: Send replay.rrweb attachment
        end
    end

    User->>+User: closes page, nagivates away, etc.
    par SentryReplaySDK to Relay
        SentryReplaySDK->>+Relay: Send replay.event update 
        SentryReplaySDK->>+Relay: Send replay.rrweb attachment 
    end
Loading

@AbhiPrasad
Copy link
Member

Just musing about connecting with the core SDK, I think there's a way here we can maybe extract out the concept of a session/user journey as a top level SDK concept, and then make replay piggy back off of that.

At the current moment I see the session (user journey) as the horizontal concept (single service over time), while the trace becomes the vertical (multiple services as they interact) - the fact that performance monitoring is coupled to the trace and replay is to the session is an implementation detail of the packages (@sentry/tracing or @sentry/replay), but the core concepts should be lifted up to the core SDKs. I have to think about this a little more though.

The session should probably have an inactivity timeout

Will this timeout be activity based like performance, or a hard timeout? We are planning to switch to a quiescence based double timeout system for idle transactions (idle and final timeout) in browser performance monitoring.

When y'all have something more formalized I would invite you to come to the Client Infra TSC - where we can share and ideate with the rest of the other SDK teams as well.

cc @k-fish because he's been experimenting with similar for performance for sessions: getsentry/sentry-javascript#4913

@JoshFerge
Copy link
Member

JoshFerge commented Apr 26, 2022

another chart, sentry entities as they function today.

gantt
    title Sentry Entity Relations (Browser)
    dateFormat  s ss 
    section User
    navigation event : milestone, m1, 10s
    section Replay
    Spans multiple pageviews, navigation events   :a1, 10s
    section Sessions
    one per pageview      :0,5s
    s2      :5s
    section trace
    one per pageview      :0, 5s
    t2      : 5s
    section transaction
    tx1 :0,  1s
    tx1 : 1s
    tx1 : 1s
    tx1 :  1s
    section error
    e1 : milestone, m5, 5s
Loading

@bruno-garcia
Copy link
Member

bruno-garcia commented Apr 26, 2022

Just musing about connecting with the core SDK, I think there's a way here we can maybe extract out the concept of a session/user journey as a top level SDK concept, and then make replay piggy back off of that.

At the current moment I see the session (user journey) as the horizontal concept (single service over time), while the trace becomes the vertical (multiple services as they interact) - the fact that performance monitoring is coupled to the trace and replay is to the session is an implementation detail of the packages (@sentry/tracing or @sentry/replay), but the core concepts should be lifted up to the core SDKs. I have to think about this a little more though.

The session should probably have an inactivity timeout

Will this timeout be activity based like performance, or a hard timeout? We are planning to switch to a quiescence based double timeout system for idle transactions (idle and final timeout) in browser performance monitoring.

When y'all have something more formalized I would invite you to come to the Client Infra TSC - where we can share and ideate with the rest of the other SDK teams as well.

cc @k-fish because he's been experimenting with similar for performance for sessions: getsentry/sentry-javascript#4913

Worth noting Sessions on mobile close when the device app is not on the foreground for 30 seconds. That might not be possible on Web but it's possible on Desktop too and as a concept can exist at least for those environments.

If the reply was tied to the transactions, at least it would solve the problem of breaking them up, but I agree having a reply of the overall session (even if practically would mean stitching together the replays of each transaction) would be a good product experience

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants