@thru/replay 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -419,12 +419,26 @@ var ReplayStream = class {
419
419
  this.logger.info(
420
420
  `replay entering BACKFILLING state (startSlot=${startSlot}, safetyMargin=${safetyMargin})`
421
421
  );
422
+ let emptyPageRetries = 0;
423
+ const MAX_EMPTY_PAGE_RETRIES = 10;
422
424
  while (!backfillDone) {
423
- const page = await fetchBackfill({ startSlot, cursor });
425
+ const page = await currentFetchBackfill({ startSlot, cursor });
424
426
  if (!page.items.length && !page.cursor && !page.done) {
425
- this.logger.warn("empty backfill page without cursor; retrying");
427
+ emptyPageRetries++;
428
+ if (emptyPageRetries > MAX_EMPTY_PAGE_RETRIES) {
429
+ this.logger.error(
430
+ `backfill returned ${MAX_EMPTY_PAGE_RETRIES} consecutive empty pages; treating as done`
431
+ );
432
+ break;
433
+ }
434
+ const backoffMs = calculateBackoff(emptyPageRetries - 1, DEFAULT_RETRY_CONFIG);
435
+ this.logger.warn(
436
+ `empty backfill page without cursor; retrying in ${backoffMs}ms (${emptyPageRetries}/${MAX_EMPTY_PAGE_RETRIES})`
437
+ );
438
+ await delay(backoffMs);
426
439
  continue;
427
440
  }
441
+ emptyPageRetries = 0;
428
442
  const sorted = [...page.items].sort(
429
443
  (a, b) => compareBigint(extractSlot(a), extractSlot(b))
430
444
  );
@@ -550,19 +564,20 @@ var ReplayStream = class {
550
564
  async *miniBackfill(fromSlot, fetchBackfill, extractSlot, keyOf, seenItem, recordEmission) {
551
565
  this.logger.info(`mini-backfill starting from slot ${fromSlot}`);
552
566
  const MINI_BACKFILL_TIMEOUT = 3e4;
553
- const startTime = Date.now();
567
+ let lastProgressTime = Date.now();
554
568
  let cursor;
555
569
  let itemsYielded = 0;
556
570
  try {
557
571
  while (true) {
558
- if (Date.now() - startTime > MINI_BACKFILL_TIMEOUT) {
559
- this.logger.warn(`mini-backfill timed out after ${MINI_BACKFILL_TIMEOUT}ms`);
572
+ if (Date.now() - lastProgressTime > MINI_BACKFILL_TIMEOUT) {
573
+ this.logger.warn(`mini-backfill timed out after ${MINI_BACKFILL_TIMEOUT}ms with no progress`);
560
574
  break;
561
575
  }
562
576
  const page = await fetchBackfill({ startSlot: fromSlot, cursor });
563
577
  const sorted = [...page.items].sort(
564
578
  (a, b) => compareBigint(extractSlot(a), extractSlot(b))
565
579
  );
580
+ let pageYielded = 0;
566
581
  for (const item of sorted) {
567
582
  const slot = extractSlot(item);
568
583
  const key = keyOf(item);
@@ -572,9 +587,11 @@ var ReplayStream = class {
572
587
  }
573
588
  recordEmission(slot, key);
574
589
  itemsYielded++;
590
+ pageYielded++;
575
591
  this.metrics.emittedReconnect += 1;
576
592
  yield item;
577
593
  }
594
+ if (pageYielded > 0) lastProgressTime = Date.now();
578
595
  cursor = page.cursor;
579
596
  if (page.done || cursor === void 0) break;
580
597
  }
@@ -588,10 +605,12 @@ var ReplayStream = class {
588
605
  };
589
606
  async function safeClose(pump) {
590
607
  try {
591
- await Promise.race([
592
- pump.close(),
593
- new Promise((resolve) => setTimeout(resolve, 5e3))
608
+ const result = await Promise.race([
609
+ pump.close().then(() => "closed"),
610
+ new Promise((resolve) => setTimeout(() => resolve("timeout"), 5e3))
594
611
  ]);
612
+ if (result === "timeout") {
613
+ }
595
614
  } catch {
596
615
  }
597
616
  }