Skip to content

Commit 29c651d

Browse files
authored
ref(replay): Avoid duplicate debounce timers (#6863)
1 parent 71432dd commit 29c651d

File tree

2 files changed

+7
-59
lines changed

2 files changed

+7
-59
lines changed

packages/replay/src/util/debounce.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function debounce(func: CallbackFunction, wait: number, options?: Debounc
5757
}
5858
timerId = setTimeout(invokeFunc, wait);
5959

60-
if (maxWait && maxTimerId === undefined) {
60+
if (maxWait && maxTimerId === undefined && maxWait !== wait) {
6161
maxTimerId = setTimeout(invokeFunc, maxWait);
6262
}
6363

packages/replay/test/integration/sendReplayEvent.test.ts

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ describe('Integration | sendReplayEvent', () => {
3636

3737
({ replay } = await mockSdk({
3838
replayOptions: {
39+
flushMinDelay: 5_000,
40+
flushMaxDelay: 15_000,
3941
stickySession: false,
4042
_experiments: {
4143
captureExceptions: true,
@@ -146,13 +148,13 @@ describe('Integration | sendReplayEvent', () => {
146148
expect(replay.eventBuffer?.pendingLength).toBe(0);
147149
});
148150

149-
it('uploads a replay event if 15 seconds have elapsed since the last replay upload', async () => {
151+
it('uploads a replay event if maxFlushDelay is set 15 seconds have elapsed since the last replay upload', async () => {
150152
const TEST_EVENT = { data: {}, timestamp: BASE_TIMESTAMP, type: 3 };
151153
// Fire a new event every 4 seconds, 4 times
152-
[...Array(4)].forEach(() => {
154+
for (let i = 0; i < 4; i++) {
153155
mockRecord._emitter(TEST_EVENT);
154-
jest.advanceTimersByTime(4000);
155-
});
156+
jest.advanceTimersByTime(4_000);
157+
}
156158

157159
// We are at time = +16seconds now (relative to BASE_TIMESTAMP)
158160
// The next event should cause an upload immediately
@@ -247,60 +249,6 @@ describe('Integration | sendReplayEvent', () => {
247249
expect(replay.eventBuffer?.pendingLength).toBe(0);
248250
});
249251

250-
it('uploads a replay event if 5 seconds have elapsed since the last replay event occurred', async () => {
251-
const TEST_EVENT = { data: {}, timestamp: BASE_TIMESTAMP, type: 3 };
252-
mockRecord._emitter(TEST_EVENT);
253-
// Pretend 5 seconds have passed
254-
const ELAPSED = 5000;
255-
await advanceTimers(ELAPSED);
256-
257-
expect(mockRecord.takeFullSnapshot).not.toHaveBeenCalled();
258-
expect(mockTransportSend).toHaveBeenCalledTimes(1);
259-
expect(replay).toHaveLastSentReplay({ recordingData: JSON.stringify([TEST_EVENT]) });
260-
261-
// No user activity to trigger an update
262-
expect(replay.session?.lastActivity).toBe(BASE_TIMESTAMP);
263-
expect(replay.session?.segmentId).toBe(1);
264-
265-
// events array should be empty
266-
expect(replay.eventBuffer?.pendingLength).toBe(0);
267-
});
268-
269-
it('uploads a replay event if 15 seconds have elapsed since the last replay upload', async () => {
270-
const TEST_EVENT = { data: {}, timestamp: BASE_TIMESTAMP, type: 3 };
271-
// Fire a new event every 4 seconds, 4 times
272-
[...Array(4)].forEach(() => {
273-
mockRecord._emitter(TEST_EVENT);
274-
jest.advanceTimersByTime(4000);
275-
});
276-
277-
// We are at time = +16seconds now (relative to BASE_TIMESTAMP)
278-
// The next event should cause an upload immediately
279-
mockRecord._emitter(TEST_EVENT);
280-
await new Promise(process.nextTick);
281-
282-
expect(replay).toHaveLastSentReplay({
283-
recordingData: JSON.stringify([...Array(5)].map(() => TEST_EVENT)),
284-
});
285-
286-
// There should also not be another attempt at an upload 5 seconds after the last replay event
287-
mockTransportSend.mockClear();
288-
await advanceTimers(DEFAULT_FLUSH_MIN_DELAY);
289-
290-
expect(replay).not.toHaveLastSentReplay();
291-
292-
expect(replay.session?.lastActivity).toBe(BASE_TIMESTAMP);
293-
expect(replay.session?.segmentId).toBe(1);
294-
// events array should be empty
295-
expect(replay.eventBuffer?.pendingLength).toBe(0);
296-
297-
// Let's make sure it continues to work
298-
mockTransportSend.mockClear();
299-
mockRecord._emitter(TEST_EVENT);
300-
await advanceTimers(DEFAULT_FLUSH_MIN_DELAY);
301-
expect(replay).toHaveLastSentReplay({ recordingData: JSON.stringify([TEST_EVENT]) });
302-
});
303-
304252
it('uploads a dom breadcrumb 5 seconds after listener receives an event', async () => {
305253
domHandler({
306254
name: 'click',

0 commit comments

Comments
 (0)