@secondlayer/subgraphs 1.3.0 → 1.3.2

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.
@@ -1440,6 +1440,8 @@ function avgEventsPerBlock(batch) {
1440
1440
 
1441
1441
  // src/runtime/reindex.ts
1442
1442
  var LOG_INTERVAL = 1000;
1443
+ var HEALTH_FLUSH_INTERVAL = 1000;
1444
+ var PROGRESS_FLUSH_INTERVAL_MS = 5000;
1443
1445
  var HOBBY_REINDEX_BATCH_CONFIG = {
1444
1446
  defaultBatchSize: 50,
1445
1447
  minBatchSize: 25,
@@ -1510,10 +1512,26 @@ async function processBlockRange(def, opts) {
1510
1512
  let blocksProcessed = 0;
1511
1513
  let totalEventsProcessed = 0;
1512
1514
  let totalErrors = 0;
1515
+ let pendingEventsProcessed = 0;
1516
+ let pendingErrors = 0;
1517
+ let pendingLastError;
1518
+ let lastHealthFlushBlock = 0;
1519
+ let lastHealthFlushAt = Date.now();
1520
+ let lastProgressFlushAt = Date.now();
1513
1521
  const batchConfig = resolveReindexBatchConfig();
1514
1522
  let batchSize = batchConfig.defaultBatchSize;
1515
1523
  let currentHeight = fromBlock;
1516
1524
  let aborted = false;
1525
+ const flushHealth = async () => {
1526
+ if (pendingEventsProcessed === 0 && pendingErrors === 0)
1527
+ return;
1528
+ await recordSubgraphProcessed2(targetDb, subgraphName, pendingEventsProcessed, pendingErrors, pendingLastError);
1529
+ pendingEventsProcessed = 0;
1530
+ pendingErrors = 0;
1531
+ pendingLastError = undefined;
1532
+ lastHealthFlushBlock = blocksProcessed;
1533
+ lastHealthFlushAt = Date.now();
1534
+ };
1517
1535
  let nextBatchEnd = Math.min(currentHeight + batchSize - 1, toBlock);
1518
1536
  let nextBatchPromise = loadBlockRange(sourceDb, currentHeight, nextBatchEnd);
1519
1537
  while (currentHeight <= toBlock) {
@@ -1556,22 +1574,31 @@ async function processBlockRange(def, opts) {
1556
1574
  });
1557
1575
  batchFailedBlocks.push({ height, reason: "processing_error" });
1558
1576
  await updateSubgraphStatus2(targetDb, subgraphName, status, height).catch(() => {});
1559
- await recordSubgraphProcessed2(targetDb, subgraphName, 0, 1, errorMsg).catch(() => {});
1560
1577
  blocksProcessed++;
1561
1578
  totalErrors++;
1579
+ pendingErrors++;
1580
+ pendingLastError = errorMsg;
1562
1581
  continue;
1563
1582
  }
1564
1583
  blocksProcessed++;
1565
1584
  totalEventsProcessed += result.processed;
1566
1585
  totalErrors += result.errors;
1586
+ pendingEventsProcessed += result.processed;
1587
+ pendingErrors += result.errors;
1588
+ if (result.errors > 0) {
1589
+ pendingLastError = `${result.errors} error(s) while processing block ${height}`;
1590
+ }
1567
1591
  if (result.timing) {
1568
1592
  stats.record(result.timing, result.processed);
1569
1593
  if (stats.shouldFlush()) {
1570
1594
  await stats.flush(targetDb);
1571
1595
  }
1572
1596
  }
1573
- if (blocksProcessed % 100 === 0) {
1597
+ const now = Date.now();
1598
+ const shouldFlushProgress = blocksProcessed % 100 === 0 || now - lastProgressFlushAt >= PROGRESS_FLUSH_INTERVAL_MS;
1599
+ if (shouldFlushProgress) {
1574
1600
  await updateSubgraphStatus2(targetDb, subgraphName, status, height);
1601
+ lastProgressFlushAt = now;
1575
1602
  }
1576
1603
  if (blocksProcessed % LOG_INTERVAL === 0) {
1577
1604
  logger5.info(`${status === "reindexing" ? "Reindex" : "Backfill"} progress`, {
@@ -1583,6 +1610,13 @@ async function processBlockRange(def, opts) {
1583
1610
  });
1584
1611
  }
1585
1612
  }
1613
+ if (status === "reindexing" && blocksProcessed > 0) {
1614
+ await updateSubgraphStatus2(targetDb, subgraphName, status, batchEnd);
1615
+ }
1616
+ const shouldFlushHealth = blocksProcessed - lastHealthFlushBlock >= HEALTH_FLUSH_INTERVAL || Date.now() - lastHealthFlushAt >= PROGRESS_FLUSH_INTERVAL_MS;
1617
+ if (shouldFlushHealth) {
1618
+ await flushHealth();
1619
+ }
1586
1620
  if (batchFailedBlocks.length > 0 && opts.subgraphId) {
1587
1621
  const gaps = coalesceFailedBlocks(batchFailedBlocks);
1588
1622
  await recordGapBatch(targetDb, opts.subgraphId, subgraphName, gaps).catch((err) => {
@@ -1600,6 +1634,7 @@ async function processBlockRange(def, opts) {
1600
1634
  currentHeight = batchEnd + 1;
1601
1635
  }
1602
1636
  await stats.flush(targetDb);
1637
+ await flushHealth();
1603
1638
  return { blocksProcessed, totalEventsProcessed, totalErrors, aborted };
1604
1639
  }
1605
1640
  async function resolveBlockRange(sourceDb, def, opts) {
@@ -1645,6 +1680,10 @@ async function reindexSubgraph(def, opts) {
1645
1680
  last_processed_block: initialReindexProgressBlock(fromBlock),
1646
1681
  reindex_from_block: fromBlock,
1647
1682
  reindex_to_block: toBlock,
1683
+ total_processed: 0,
1684
+ total_errors: 0,
1685
+ last_error: null,
1686
+ last_error_at: null,
1648
1687
  updated_at: new Date
1649
1688
  }).where("name", "=", subgraphName).execute();
1650
1689
  logger5.info("Reindexing blocks", {
@@ -1676,10 +1715,6 @@ async function reindexSubgraph(def, opts) {
1676
1715
  }
1677
1716
  return { processed: result.blocksProcessed };
1678
1717
  }
1679
- const { recordSubgraphProcessed: recordSubgraphProcessed3 } = await import("@secondlayer/shared/db/queries/subgraphs");
1680
- if (result.totalEventsProcessed > 0 || result.totalErrors > 0) {
1681
- await recordSubgraphProcessed3(targetDb, subgraphName, result.totalEventsProcessed, result.totalErrors, result.totalErrors > 0 ? `${result.totalErrors} error(s) during reindex` : undefined);
1682
- }
1683
1718
  await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
1684
1719
  await clearReindexMetadata(targetDb, subgraphName);
1685
1720
  logger5.info("Reindex complete", {
@@ -1755,10 +1790,6 @@ async function resumeReindex(def, opts) {
1755
1790
  }
1756
1791
  return { processed: result.blocksProcessed };
1757
1792
  }
1758
- const { recordSubgraphProcessed: recordSubgraphProcessed3 } = await import("@secondlayer/shared/db/queries/subgraphs");
1759
- if (result.totalEventsProcessed > 0 || result.totalErrors > 0) {
1760
- await recordSubgraphProcessed3(targetDb, subgraphName, result.totalEventsProcessed, result.totalErrors, result.totalErrors > 0 ? `${result.totalErrors} error(s) during resumed reindex` : undefined);
1761
- }
1762
1793
  await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
1763
1794
  await clearReindexMetadata(targetDb, subgraphName);
1764
1795
  logger5.info("Resumed reindex complete", {
@@ -1805,10 +1836,6 @@ async function backfillSubgraph(def, opts) {
1805
1836
  resolved
1806
1837
  });
1807
1838
  }
1808
- const { recordSubgraphProcessed: recordSubgraphProcessed3 } = await import("@secondlayer/shared/db/queries/subgraphs");
1809
- if (result.totalEventsProcessed > 0 || result.totalErrors > 0) {
1810
- await recordSubgraphProcessed3(targetDb, subgraphName, result.totalEventsProcessed, result.totalErrors, result.totalErrors > 0 ? `${result.totalErrors} error(s) during backfill` : undefined);
1811
- }
1812
1839
  logger5.info("Backfill complete", {
1813
1840
  subgraph: subgraphName,
1814
1841
  blocks: result.blocksProcessed,
@@ -2720,7 +2747,7 @@ async function startSubgraphOperationRunner(opts) {
2720
2747
  }, HEARTBEAT_INTERVAL_MS);
2721
2748
  const cancelPoll = setInterval(() => {
2722
2749
  getSubgraphOperation(db, operation.id).then((row) => {
2723
- if (row?.cancel_requested && !controller.signal.aborted) {
2750
+ if ((!row || row.cancel_requested) && !controller.signal.aborted) {
2724
2751
  controller.abort("user-cancelled");
2725
2752
  }
2726
2753
  }).catch((err) => {
@@ -2930,5 +2957,5 @@ var shutdown = async () => {
2930
2957
  process.on("SIGINT", shutdown);
2931
2958
  process.on("SIGTERM", shutdown);
2932
2959
 
2933
- //# debugId=48A79220FFF1766364756E2164756E21
2960
+ //# debugId=C53337E6DAF60BED64756E2164756E21
2934
2961
  //# sourceMappingURL=service.js.map