-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat(replay): Ensure min/max duration when flushing #8596
Conversation
size-limit report 📦
|
packages/replay/src/constants.ts
Outdated
@@ -45,3 +45,8 @@ export const SLOW_CLICK_SCROLL_TIMEOUT = 300; | |||
|
|||
/** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */ | |||
export const REPLAY_MAX_EVENT_BUFFER_SIZE = 20_000_000; // ~20MB | |||
|
|||
/** Replays must be min. 4s long before we send them. */ | |||
export const MIN_REPLAY_DURATION = 4_000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this 5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe let's make it 4_999
, wanted to ensure we avoid race conditions with the 5s flush delay...?
@@ -51,6 +56,7 @@ export class Replay implements Integration { | |||
public constructor({ | |||
flushMinDelay = DEFAULT_FLUSH_MIN_DELAY, | |||
flushMaxDelay = DEFAULT_FLUSH_MAX_DELAY, | |||
minReplayDuration = MIN_REPLAY_DURATION, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should DEFAULT_FLUSH_MIN_DELAY = MIN_REPLAY_DURATION?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or probably MIN_REPLAY_DURATION + small delay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd set them up for 5_000 flush delay, 4_999 min duration..?
@@ -1100,6 +1101,23 @@ export class ReplayContainer implements ReplayContainerInterface { | |||
return; | |||
} | |||
|
|||
const start = this._context.initialTimestamp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is reliable to use as the start of the session? We should trace where this and the session start gets updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we cannot use session.start
here as that may be outdated for e.g. buffer session etc. What we care about (?? I think at least?) is the first event that may actually be sent, which should be this timestamp?
|
||
// If session is too short, or too long (allow some wiggle room over maxSessionLife), do not send it | ||
// This _should_ not happen, but it may happen if flush is triggered due to a page activity change or similar | ||
if (duration < this._options.minReplayDuration || duration > this.timeouts.maxSessionLife + 5_000) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have different logic if replay is too long? e.g. it needs to start a new session (though that logic could be where the bug is).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, we have a bunch of logic for this (and tests...), so ideally it should really not happen (but it is 😬 ). IMHO I'd get out this fix, I also added some logic to log out when this happens, so maybe we can look at this then to help figure out why this even happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we log out when we update initialTimestamp
and session start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add another log for this! 👍
7c90552
to
98eeb59
Compare
@@ -981,6 +982,9 @@ export class ReplayContainer implements ReplayContainerInterface { | |||
|
|||
const earliestEvent = eventBuffer.getEarliestTimestamp(); | |||
if (earliestEvent && earliestEvent < this._context.initialTimestamp) { | |||
// eslint-disable-next-line no-console | |||
const log = this.getOptions()._experiments.traceInternals ? console.info : logger.info; | |||
__DEBUG_BUILD__ && log(`[Replay] Updating initial timestamp to ${earliestEvent}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@billyvg added this log here, that's the only place that updates this (apart from initial setup, which sets it to Date.now()
by default).
da0d42a
to
44f58c4
Compare
This PR adds a safeguard to ensure we do not flush (=send) a replay that is either too short or too long.
We allow to configure a
minReplayDuration
, which defaults to 5s and maxes out at 15s. Whenever we try to flush and the duration is shorter than this, we'll just skip flushing.Additionally, we also skip flushing if the replay is longer than MAX_SESSION_LIFE + 5s (=60min + 5s). This should not happen, technically, but apparently it still does. So while we figure out the root cause of this, we can at least avoid sending stuff in that case.