Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [RUMF-997] dont take a FullSnapshot on view creation during session renew #1011

Merged

Conversation

BenoitZugmeyer
Copy link
Member

Motivation

When renewing the session from replay to lite (for example), a full snapshot was taken on the lite session, because the recording was stopped a tiny bit too late (after the new view creation)

Changes

This PR introduces a new lifecycle event SESSION_EXPIRED to have a chance to do some cleanup before the session is renewed. It uses it to stop recording.

Testing

Manual, e2e (no unit test because we don't have any test at this level: it involves the whole RUM and recording stack)


I have gone over the contributing documentation.

A full snapshot was incorrectly taken when renewing the session because
`startRecording` is called before initializing the recorder. So when a
session is renewed, we first create a new view then we stop recording:

```
notify SESSION_RENEWED
  -> notify VIEW_CREATED   (trackViews)
    -> takeFullSnapshot()  (startRecording)
  -> stopRecording()       (recorderApi)
  -> startRecording()      (recorderApi)
```

This commit uses the newly introduced lifecycle event triggered before
SESSION_RENEWED to stop recording when the session is expired:

```
notify SESSION_EXPIRED
  -> stopRecording()
notify SESSION_RENEWED
  -> notify VIEW_CREATED
    -> (nothing happens since recording is stopped)
  -> startRecording()
```
to ensure a single fullsnapshot is taken when renewing the session
@BenoitZugmeyer BenoitZugmeyer requested a review from a team as a code owner August 24, 2021 09:51
@@ -62,12 +62,14 @@ export function makeRecorderApi(startRecordingImpl: StartRecording): RecorderApi
session: RumSession,
parentContexts: ParentContexts
) => {
lifeCycle.subscribe(LifeCycleEventType.SESSION_RENEWED, () => {
lifeCycle.subscribe(LifeCycleEventType.SESSION_EXPIRED, () => {
if (state.status === RecorderStatus.Started) {
stopStrategy()
state = { status: RecorderStatus.IntentToStart }
Copy link
Contributor

Choose a reason for hiding this comment

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

If a session expired, we might not need to restart it if it's now LITE no?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think what you're referring to is a few lines below in the startStrategy

startStrategy = () => {
if (!session.hasReplayPlan()) {
state = { status: RecorderStatus.IntentToStart }
return
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes start does not necessarily start recording 😅 it is the function exposed to the customer, so if it is called when the session has no replay plan, it will just set the state to back IntentToStart.

// This implementation is "good enough" for our use-cases. Improving this is not trivial,
// primarily because multiple instances of the SDK may be managing the same session cookie at
// the same time, for example when using Logs and RUM on the same page, or opening multiple tabs
// on the same domain.
Copy link
Contributor

Choose a reason for hiding this comment

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

Good comment!

@@ -62,12 +62,14 @@ export function makeRecorderApi(startRecordingImpl: StartRecording): RecorderApi
session: RumSession,
parentContexts: ParentContexts
) => {
lifeCycle.subscribe(LifeCycleEventType.SESSION_RENEWED, () => {
lifeCycle.subscribe(LifeCycleEventType.SESSION_EXPIRED, () => {
if (state.status === RecorderStatus.Started) {
stopStrategy()
state = { status: RecorderStatus.IntentToStart }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think what you're referring to is a few lines below in the startStrategy

startStrategy = () => {
if (!session.hasReplayPlan()) {
state = { status: RecorderStatus.IntentToStart }
return
}

@BenoitZugmeyer BenoitZugmeyer merged commit 636989e into main Aug 26, 2021
@BenoitZugmeyer BenoitZugmeyer deleted the benoit/dont-take-fs-on-view-creation-during-session-renew branch August 26, 2021 15:17
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.

4 participants