Skip to content

Commit 216517f

Browse files
committed
feat(replay): Do not capture replays < 5 seconds
Promotes the feature from #7949 to GA. Do not immediately flush on snapshot checkouts, instead delay by minimum flush delay (5 seconds). This means that we will not collect replays < 5 seconds. e.g. User opens site and immediately closes the tab. Closes getsentry/team-replay#65
1 parent 9ed5cfd commit 216517f

File tree

6 files changed

+66
-857
lines changed

6 files changed

+66
-857
lines changed

packages/replay/src/replay.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,13 @@ export class ReplayContainer implements ReplayContainerInterface {
510510
return this.flushImmediate();
511511
}
512512

513+
/**
514+
* Flush using debounce flush
515+
*/
516+
public flush(): Promise<void> {
517+
return this._debouncedFlush() as Promise<void>;
518+
}
519+
513520
/**
514521
* Always flush via `_debouncedFlush` so that we do not have flushes triggered
515522
* from calling both `flush` and `_debouncedFlush`. Otherwise, there could be

packages/replay/src/types/replay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions {
184184
scrollTimeout: number;
185185
ignoreSelectors: string[];
186186
};
187-
delayFlushOnCheckout: number;
188187
}>;
189188
}
190189

@@ -421,6 +420,7 @@ export interface ReplayContainer {
421420
stopRecording(): boolean;
422421
sendBufferedReplayOrFlush(options?: SendBufferedReplayOptions): Promise<void>;
423422
conditionalFlush(): Promise<void>;
423+
flush(): Promise<void>;
424424
flushImmediate(): Promise<void>;
425425
cancelFlush(): void;
426426
triggerUserActivity(): void;

packages/replay/src/util/handleRecordingEmit.ts

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -80,37 +80,12 @@ export function getHandleRecordingEmit(replay: ReplayContainer): RecordingEmitCa
8080
}
8181
}
8282

83-
const options = replay.getOptions();
84-
85-
// TODO: We want this as an experiment so that we can test
86-
// internally and create metrics before making this the default
87-
if (options._experiments.delayFlushOnCheckout) {
83+
if (replay.recordingMode === 'session') {
8884
// If the full snapshot is due to an initial load, we will not have
8985
// a previous session ID. In this case, we want to buffer events
9086
// for a set amount of time before flushing. This can help avoid
9187
// capturing replays of users that immediately close the window.
92-
setTimeout(() => replay.conditionalFlush(), options._experiments.delayFlushOnCheckout);
93-
94-
// Cancel any previously debounced flushes to ensure there are no [near]
95-
// simultaneous flushes happening. The latter request should be
96-
// insignificant in this case, so wait for additional user interaction to
97-
// trigger a new flush.
98-
//
99-
// This can happen because there's no guarantee that a recording event
100-
// happens first. e.g. a mouse click can happen and trigger a debounced
101-
// flush before the checkout.
102-
replay.cancelFlush();
103-
104-
return true;
105-
}
106-
107-
// Flush immediately so that we do not miss the first segment, otherwise
108-
// it can prevent loading on the UI. This will cause an increase in short
109-
// replays (e.g. opening and closing a tab quickly), but these can be
110-
// filtered on the UI.
111-
if (replay.recordingMode === 'session') {
112-
// We want to ensure the worker is ready, as otherwise we'd always send the first event uncompressed
113-
void replay.flushImmediate();
88+
void replay.flush();
11489
}
11590

11691
return true;

packages/replay/test/integration/coreHandlers/handleAfterSendEvent.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,13 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => {
148148

149149
jest.runAllTimers();
150150
await new Promise(process.nextTick);
151-
152151
// Send twice, one for the error & one right after for the session conversion
152+
expect(mockSend).toHaveBeenCalledTimes(1);
153+
154+
jest.runAllTimers();
155+
await new Promise(process.nextTick);
153156
expect(mockSend).toHaveBeenCalledTimes(2);
157+
154158
// This is removed now, because it has been converted to a "session" session
155159
expect(Array.from(replay.getContext().errorIds)).toEqual([]);
156160
expect(replay.isEnabled()).toBe(true);

0 commit comments

Comments
 (0)