Skip to content

Commit 91c75eb

Browse files
authored
Renamed LeadingCapture to ScheduledCapture (#1363)
1 parent 0a7e97a commit 91c75eb

File tree

5 files changed

+157
-153
lines changed

5 files changed

+157
-153
lines changed

src/browser/replay/replayManager.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import id from '../../tracing/id.js';
33
import logger from '../../logger.js';
44
import Recorder from './recorder.js';
55
import ReplayPredicates from './replayPredicates.js';
6-
import LeadingCapture from './leadingCapture.js';
6+
import ScheduledCapture from './scheduledCapture.js';
77

88
/** @typedef {import('./recorder.js').BufferCursor} BufferCursor */
99
/** @typedef {import('./recorder.js').Recorder} Recorder */
@@ -29,7 +29,7 @@ export default class ReplayManager {
2929
_recorder;
3030
_tracing;
3131
_telemeter;
32-
_leadingCapture;
32+
_scheduledCapture;
3333
_trailingStatus;
3434

3535
/**
@@ -50,37 +50,37 @@ export default class ReplayManager {
5050
this._telemeter = telemeter;
5151
this._trailingStatus = new Map();
5252
this._predicates = new ReplayPredicates(options);
53-
this._leadingCapture = new LeadingCapture({
53+
this._scheduledCapture = new ScheduledCapture({
5454
recorder: this._recorder,
5555
tracing: this._tracing,
5656
telemeter: this._telemeter,
57-
shouldSend: this._shouldSendLeading.bind(this),
58-
onComplete: this._onLeadingComplete.bind(this),
57+
shouldSend: this._shouldSendScheduled.bind(this),
58+
onComplete: this._onScheduledComplete.bind(this),
5959
});
6060
}
6161

6262
/**
63-
* Called when a leading capture completes (sent or discarded).
63+
* Called when a scheduled capture completes (sent or discarded).
6464
* Cleans up the trailing status coordination state.
6565
*
6666
* @param {string} replayId - The replay ID
6767
* @private
6868
*/
69-
_onLeadingComplete(replayId) {
69+
_onScheduledComplete(replayId) {
7070
this._trailingStatus.delete(replayId);
7171
}
7272

7373
/**
74-
* Determines if a leading replay should be sent based on coordination state.
74+
* Determines if a scheduled replay should be sent based on coordination state.
7575
*
76-
* Leading replays can only be sent after the trailing replay has been
76+
* Scheduled replays can only be sent after the trailing replay has been
7777
* successfully sent or explicitly skipped (for leading-only captures).
7878
*
7979
* @param {string} replayId - The replay ID
80-
* @returns {boolean} True if leading replay can be sent
80+
* @returns {boolean} True if scheduled replay can be sent
8181
* @private
8282
*/
83-
_shouldSendLeading(replayId) {
83+
_shouldSendScheduled(replayId) {
8484
const status = this._trailingStatus.get(replayId);
8585
return status === TrailingStatus.SENT || status === TrailingStatus.SKIPPED;
8686
}
@@ -125,7 +125,7 @@ export default class ReplayManager {
125125

126126
const leadingSeconds = this._recorder.options?.postDuration || 0;
127127
if (leadingSeconds > 0) {
128-
this._leadingCapture.schedule(replayId, occurrenceUuid, leadingSeconds);
128+
this._scheduledCapture.schedule(replayId, occurrenceUuid, leadingSeconds);
129129
this._trailingStatus.set(replayId, TrailingStatus.PENDING);
130130
}
131131
}
@@ -263,7 +263,7 @@ export default class ReplayManager {
263263
});
264264

265265
this._trailingStatus.set(replayId, TrailingStatus.SENT);
266-
await this._leadingCapture.sendIfReady(replayId);
266+
await this._scheduledCapture.sendIfReady(replayId);
267267
}
268268

269269
/**
@@ -280,7 +280,7 @@ export default class ReplayManager {
280280
}
281281

282282
this._trailingStatus.set(replayId, TrailingStatus.FAILED);
283-
this._leadingCapture.discard(replayId);
283+
this._scheduledCapture.discard(replayId);
284284

285285
if (!this._map.has(replayId)) {
286286
logger.error(

src/browser/replay/leadingCapture.js renamed to src/browser/replay/scheduledCapture.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import logger from '../../logger.js';
33
/** @typedef {import('./recorder.js').BufferCursor} BufferCursor */
44

55
/**
6-
* Manages delayed "leading" (post-trigger) replay captures.
6+
* A utility for coordinating delayed, cursor-based captures.
77
*
8-
* Coordinates timing, buffer cursor stability, and payload preparation
9-
* for events that occur AFTER the trigger event.
8+
* Manages timer-based capture scheduling, buffer cursor stability across
9+
* checkouts, and payload preparation. Used primarily for capturing events
10+
* that occur after a trigger (leading replays), but the implementation is
11+
* generic and could be used for any delayed capture scenario.
1012
*/
11-
export default class LeadingCapture {
13+
export default class ScheduledCapture {
1214
_recorder;
1315
_tracing;
1416
_telemeter;
@@ -17,7 +19,7 @@ export default class LeadingCapture {
1719
_onComplete;
1820

1921
/**
20-
* Creates a new LeadingCapture instance
22+
* Creates a new ScheduledCapture instance
2123
*
2224
* @param {Object} props - Configuration object
2325
* @param {Object} props.recorder - Recorder instance for capturing events

test/replay/integration/replayManager.bufferIndex.checkoutResilience.test.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
7272
await clock.tickAsync(100);
7373

7474
const cursor =
75-
replayManager._leadingCapture._pending.get(replayId).bufferCursor;
75+
replayManager._scheduledCapture._pending.get(replayId).bufferCursor;
7676
expect(cursor).to.be.an('object');
7777
expect(cursor.slot).to.equal(0);
7878

@@ -107,7 +107,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
107107
{ resourceSpans: [{ spanData: 'test' }] },
108108
{ 'X-Rollbar-Replay-Id': replayId },
109109
]);
110-
expect(replayManager._leadingCapture._pending.size).to.equal(0);
110+
expect(replayManager._scheduledCapture._pending.size).to.equal(0);
111111

112112
recorder.exportRecordingSpan.restore();
113113
});
@@ -165,7 +165,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
165165
{ resourceSpans: [{ spanData: 'test' }] },
166166
{ 'X-Rollbar-Replay-Id': replayId },
167167
]);
168-
expect(replayManager._leadingCapture._pending.size).to.equal(0);
168+
expect(replayManager._scheduledCapture._pending.size).to.equal(0);
169169

170170
recorder.exportRecordingSpan.restore();
171171
});
@@ -195,7 +195,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
195195
await clock.tickAsync(100);
196196

197197
const cursor =
198-
replayManager._leadingCapture._pending.get(replayId).bufferCursor;
198+
replayManager._scheduledCapture._pending.get(replayId).bufferCursor;
199199
expect(cursor).to.be.an('object');
200200

201201
await clock.tickAsync(2000);
@@ -229,7 +229,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
229229
{ resourceSpans: [{ spanData: 'test' }] },
230230
{ 'X-Rollbar-Replay-Id': replayId },
231231
]);
232-
expect(replayManager._leadingCapture._pending.size).to.equal(0);
232+
expect(replayManager._scheduledCapture._pending.size).to.equal(0);
233233

234234
recorder.exportRecordingSpan.restore();
235235
});
@@ -266,7 +266,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
266266
{ resourceSpans: [{ spanData: 'test' }] },
267267
{ 'X-Rollbar-Replay-Id': replayId },
268268
]);
269-
expect(replayManager._leadingCapture._pending.size).to.equal(0);
269+
expect(replayManager._scheduledCapture._pending.size).to.equal(0);
270270
});
271271

272272
it('collects events strictly after the cursor', async function () {
@@ -292,7 +292,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
292292
await clock.tickAsync(100);
293293

294294
const cursor =
295-
replayManager._leadingCapture._pending.get(replayId).bufferCursor;
295+
replayManager._scheduledCapture._pending.get(replayId).bufferCursor;
296296

297297
sinon.spy(recorder, '_collectEventsFromCursor');
298298

@@ -315,7 +315,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
315315
{ resourceSpans: [{ spanData: 'test' }] },
316316
{ 'X-Rollbar-Replay-Id': replayId },
317317
]);
318-
expect(replayManager._leadingCapture._pending.size).to.equal(0);
318+
expect(replayManager._scheduledCapture._pending.size).to.equal(0);
319319

320320
recorder._collectEventsFromCursor.restore();
321321
});
@@ -357,7 +357,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
357357
);
358358

359359
expect(replayManager._map.has(replayId)).to.be.false;
360-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
360+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
361361
sinon.assert.notCalled(api.postSpans);
362362

363363
logger.error.restore();
@@ -401,7 +401,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
401401
{ resourceSpans: [{ spanData: 'test' }] },
402402
{ 'X-Rollbar-Replay-Id': replayId },
403403
]);
404-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
404+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
405405
});
406406

407407
it('discard cancels timer; success clears state', async function () {
@@ -422,7 +422,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
422422
replayManager.capture(replayId1, 'test-uuid-1', trigger, triggerContext);
423423
await clock.tickAsync(100);
424424

425-
expect(replayManager._leadingCapture._pending.has(replayId1)).to.be.true;
425+
expect(replayManager._scheduledCapture._pending.has(replayId1)).to.be.true;
426426

427427
replayManager.discard(replayId1);
428428
await clock.tickAsync(10000);
@@ -441,7 +441,7 @@ describe('ReplayManager – Buffer Index Checkout Resilience', function () {
441441
{ resourceSpans: [{ spanData: 'test' }] },
442442
{ 'X-Rollbar-Replay-Id': replayId2 },
443443
]);
444-
expect(replayManager._leadingCapture._pending.has(replayId2)).to.be.false;
444+
expect(replayManager._scheduledCapture._pending.has(replayId2)).to.be.false;
445445
expect(replayManager._trailingStatus.has(replayId2)).to.be.false;
446446
});
447447
});

test/replay/integration/replayManager.bufferIndex.test.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('ReplayManager buffer-index integration', function () {
8181
{ timestamp: 2000, type: EventType.Meta, data: {} },
8282
]);
8383

84-
sinon.spy(replayManager._leadingCapture, 'sendIfReady');
84+
sinon.spy(replayManager._scheduledCapture, 'sendIfReady');
8585

8686
const replayId = 'test-replay-id';
8787
const occurrenceUuid = 'test-uuid';
@@ -90,19 +90,19 @@ describe('ReplayManager buffer-index integration', function () {
9090
replayManager.capture(replayId, occurrenceUuid, triggerContext);
9191
await clock.tickAsync(100);
9292

93-
sinon.assert.notCalled(replayManager._leadingCapture.sendIfReady);
93+
sinon.assert.notCalled(replayManager._scheduledCapture.sendIfReady);
9494

9595
await replayManager.send(replayId);
96-
sinon.assert.calledOnce(replayManager._leadingCapture.sendIfReady);
96+
sinon.assert.calledOnce(replayManager._scheduledCapture.sendIfReady);
9797

9898
await clock.tickAsync(5000);
9999

100-
sinon.assert.calledTwice(replayManager._leadingCapture.sendIfReady);
100+
sinon.assert.calledTwice(replayManager._scheduledCapture.sendIfReady);
101101
expect(
102-
replayManager._leadingCapture.sendIfReady.secondCall.args,
102+
replayManager._scheduledCapture.sendIfReady.secondCall.args,
103103
).to.deep.equal([replayId]);
104104

105-
replayManager._leadingCapture.sendIfReady.restore();
105+
replayManager._scheduledCapture.sendIfReady.restore();
106106
});
107107

108108
it('captures and sends leading replay with buffer-index', async function () {
@@ -177,7 +177,7 @@ describe('ReplayManager buffer-index integration', function () {
177177
await clock.tickAsync(100);
178178

179179
const capturedCursor =
180-
replayManager._leadingCapture._pending.get(replayId).bufferCursor;
180+
replayManager._scheduledCapture._pending.get(replayId).bufferCursor;
181181
expect(capturedCursor).to.be.an('object');
182182
expect(capturedCursor).to.have.property('slot', 0);
183183
expect(capturedCursor).to.have.property('offset', 0);
@@ -205,7 +205,7 @@ describe('ReplayManager buffer-index integration', function () {
205205
{ resourceSpans: [{ spanData: 'test' }] },
206206
{ 'X-Rollbar-Replay-Id': replayId },
207207
]);
208-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
208+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
209209
});
210210

211211
it('discards leading when trailing fails', async function () {
@@ -228,7 +228,7 @@ describe('ReplayManager buffer-index integration', function () {
228228
await clock.tickAsync(5000);
229229

230230
sinon.assert.notCalled(tracing.exporter.post);
231-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
231+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
232232
});
233233

234234
it('waits while trailing is pending, then sends once trailing is SENT', async function () {
@@ -255,7 +255,8 @@ describe('ReplayManager buffer-index integration', function () {
255255

256256
await clock.tickAsync(5000);
257257

258-
const pendingContext = replayManager._leadingCapture._pending.get(replayId);
258+
const pendingContext =
259+
replayManager._scheduledCapture._pending.get(replayId);
259260
expect(pendingContext.ready).to.be.true;
260261
sinon.assert.notCalled(tracing.exporter.post);
261262

@@ -301,7 +302,7 @@ describe('ReplayManager buffer-index integration', function () {
301302
{ resourceSpans: [{ spanData: 'test' }] },
302303
{ 'X-Rollbar-Replay-Id': replayId },
303304
]);
304-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
305+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
305306
});
306307

307308
it('does not schedule leading when trailing export throws', async function () {
@@ -317,7 +318,7 @@ describe('ReplayManager buffer-index integration', function () {
317318
await clock.tickAsync(100);
318319

319320
expect(replayManager._map.has(replayId)).to.be.false;
320-
expect(replayManager._leadingCapture._pending.has(replayId)).to.be.false;
321+
expect(replayManager._scheduledCapture._pending.has(replayId)).to.be.false;
321322
});
322323

323324
it('cleanup: discard cancels timer; success clears state', async function () {
@@ -336,7 +337,7 @@ describe('ReplayManager buffer-index integration', function () {
336337
replayManager.capture(replayId1, occurrenceUuid1, triggerContext);
337338
await clock.tickAsync(100);
338339

339-
expect(replayManager._leadingCapture._pending.has(replayId1)).to.be.true;
340+
expect(replayManager._scheduledCapture._pending.has(replayId1)).to.be.true;
340341

341342
replayManager.discard(replayId1);
342343
await clock.tickAsync(10000);
@@ -370,7 +371,7 @@ describe('ReplayManager buffer-index integration', function () {
370371
{ resourceSpans: [{ spanData: 'test' }] },
371372
{ 'X-Rollbar-Replay-Id': replayId2 },
372373
]);
373-
expect(replayManager._leadingCapture._pending.has(replayId2)).to.be.false;
374+
expect(replayManager._scheduledCapture._pending.has(replayId2)).to.be.false;
374375
expect(replayManager._trailingStatus.has(replayId2)).to.be.false;
375376
});
376377
});

0 commit comments

Comments
 (0)