Skip to content

Commit c79e4fc

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 3771d05 commit c79e4fc

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
@@ -509,6 +509,13 @@ export class ReplayContainer implements ReplayContainerInterface {
509509
return this.flushImmediate();
510510
}
511511

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

packages/replay/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions {
316316
scrollTimeout: number;
317317
ignoreSelectors: string[];
318318
};
319-
delayFlushOnCheckout: number;
320319
}>;
321320
}
322321

@@ -553,6 +552,7 @@ export interface ReplayContainer {
553552
stopRecording(): boolean;
554553
sendBufferedReplayOrFlush(options?: SendBufferedReplayOptions): Promise<void>;
555554
conditionalFlush(): Promise<void>;
555+
flush(): Promise<void>;
556556
flushImmediate(): Promise<void>;
557557
cancelFlush(): void;
558558
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)