@secondlayer/subgraphs 3.23.1 → 3.23.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.
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.js +59 -50
- package/dist/src/index.js.map +4 -4
- package/dist/src/runtime/block-processor.d.ts +62 -9
- package/dist/src/runtime/block-processor.js +30 -20
- package/dist/src/runtime/block-processor.js.map +4 -4
- package/dist/src/runtime/catchup.d.ts +11 -7
- package/dist/src/runtime/catchup.js +37 -28
- package/dist/src/runtime/catchup.js.map +4 -4
- package/dist/src/runtime/context.js +12 -3
- package/dist/src/runtime/context.js.map +3 -3
- package/dist/src/runtime/processor.js +98 -89
- package/dist/src/runtime/processor.js.map +4 -4
- package/dist/src/runtime/reindex.d.ts +11 -7
- package/dist/src/runtime/reindex.js +59 -50
- package/dist/src/runtime/reindex.js.map +4 -4
- package/dist/src/runtime/reorg.d.ts +11 -7
- package/dist/src/runtime/reorg.js +44 -35
- package/dist/src/runtime/reorg.js.map +4 -4
- package/dist/src/runtime/runner.d.ts +36 -32
- package/dist/src/runtime/source-matcher.d.ts +11 -7
- package/dist/src/runtime/stats.d.ts +3 -3
- package/dist/src/schema/index.d.ts +11 -7
- package/dist/src/service.js +101 -92
- package/dist/src/service.js.map +4 -4
- package/dist/src/testing/index.d.ts +32 -28
- package/dist/src/testing/index.js +17 -8
- package/dist/src/testing/index.js.map +3 -3
- package/dist/src/triggers/index.d.ts +11 -7
- package/dist/src/types.d.ts +11 -7
- package/dist/src/validate.d.ts +11 -7
- package/package.json +1 -1
package/dist/src/service.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
3
|
|
|
4
4
|
// src/runtime/context.ts
|
|
5
|
-
import { logger } from "@secondlayer/shared/logger";
|
|
5
|
+
import { logger as logger2 } from "@secondlayer/shared/logger";
|
|
6
6
|
import { formatUnits } from "@secondlayer/stacks/utils";
|
|
7
7
|
import { sql } from "kysely";
|
|
8
8
|
|
|
@@ -147,6 +147,7 @@ function generateSubgraphSQL(def, schemaNameOverride) {
|
|
|
147
147
|
|
|
148
148
|
// src/runtime/chain-read.ts
|
|
149
149
|
import { getSourceDb } from "@secondlayer/shared/db";
|
|
150
|
+
import { logger } from "@secondlayer/shared/logger";
|
|
150
151
|
import { http, createPublicClient } from "@secondlayer/stacks";
|
|
151
152
|
import {
|
|
152
153
|
ContractResponseError,
|
|
@@ -232,6 +233,14 @@ function createChainReadClient(ctx) {
|
|
|
232
233
|
const pinnedTo = constant ? null : ctx.indexBlockHash;
|
|
233
234
|
const cached = await db.selectFrom("chain_read_cache").select("result_hex").where("contract_id", "=", contractId).where("function_name", "=", fn.name).where("args_hash", "=", argsHash).where((eb) => pinnedTo === null ? eb("index_block_hash", "is", null) : eb("index_block_hash", "=", pinnedTo)).executeTakeFirst();
|
|
234
235
|
const resultHex = cached?.result_hex ?? await gate.run(async () => {
|
|
236
|
+
if (!ctx.indexBlockHash) {
|
|
237
|
+
logger.warn("Chain read is not pinned to a block (no index_block_hash)", {
|
|
238
|
+
contractId,
|
|
239
|
+
functionName: fn.name,
|
|
240
|
+
blockHeight: ctx.blockHeight,
|
|
241
|
+
note: 'cache: "contract-constant" asserts this value cannot change; the node answered at its own tip'
|
|
242
|
+
});
|
|
243
|
+
}
|
|
235
244
|
const value2 = await readContract(nodeClient(rpcUrl), {
|
|
236
245
|
contract: contractId,
|
|
237
246
|
functionName: fn.name,
|
|
@@ -346,7 +355,7 @@ class SubgraphContext {
|
|
|
346
355
|
data: { ...key, ...row, ...meta, _upsert_keys: keyColumns }
|
|
347
356
|
});
|
|
348
357
|
} else {
|
|
349
|
-
|
|
358
|
+
logger2.warn("upsert called without matching uniqueKeys constraint, using fallback", {
|
|
350
359
|
table,
|
|
351
360
|
keys: keyColumns
|
|
352
361
|
});
|
|
@@ -906,7 +915,7 @@ function decodeFunctionArgs(args) {
|
|
|
906
915
|
|
|
907
916
|
// src/runtime/runner.ts
|
|
908
917
|
import { getErrorMessage } from "@secondlayer/shared";
|
|
909
|
-
import { logger as
|
|
918
|
+
import { logger as logger3 } from "@secondlayer/shared/logger";
|
|
910
919
|
import {
|
|
911
920
|
clarityValueToJS,
|
|
912
921
|
deserializeCV as deserializeCV3,
|
|
@@ -1257,7 +1266,7 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1257
1266
|
units.sort((a, b) => (a.tx.tx_index ?? 0) - (b.tx.tx_index ?? 0) || (a.event?.event_index ?? -1) - (b.event?.event_index ?? -1));
|
|
1258
1267
|
for (const { tx, event, sourceName } of units) {
|
|
1259
1268
|
if (errors >= threshold) {
|
|
1260
|
-
|
|
1269
|
+
logger3.error("Subgraph error threshold reached, skipping remaining events", {
|
|
1261
1270
|
subgraph: subgraph.name,
|
|
1262
1271
|
errors,
|
|
1263
1272
|
threshold
|
|
@@ -1266,7 +1275,7 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1266
1275
|
}
|
|
1267
1276
|
const handler = subgraph.handlers[sourceName] ?? subgraph.handlers["*"] ?? null;
|
|
1268
1277
|
if (!handler) {
|
|
1269
|
-
|
|
1278
|
+
logger3.warn("No handler found for source", {
|
|
1270
1279
|
subgraph: subgraph.name,
|
|
1271
1280
|
sourceName,
|
|
1272
1281
|
txId: tx.tx_id
|
|
@@ -1323,7 +1332,7 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1323
1332
|
const verdict = validatePrintPayload(filter.prints, printPayload.topic ?? "", printPayload.data ?? {});
|
|
1324
1333
|
if (!verdict.ok) {
|
|
1325
1334
|
skipped++;
|
|
1326
|
-
|
|
1335
|
+
logger3.warn("Print payload does not match declared prints schema", {
|
|
1327
1336
|
subgraph: subgraph.name,
|
|
1328
1337
|
sourceName,
|
|
1329
1338
|
topic: printPayload.topic,
|
|
@@ -1338,7 +1347,7 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1338
1347
|
} catch (err) {
|
|
1339
1348
|
ctx.rollbackTo(checkpoint);
|
|
1340
1349
|
errors++;
|
|
1341
|
-
|
|
1350
|
+
logger3.error("Subgraph handler error", {
|
|
1342
1351
|
subgraph: subgraph.name,
|
|
1343
1352
|
sourceName,
|
|
1344
1353
|
txId: tx.tx_id,
|
|
@@ -1623,7 +1632,7 @@ import {
|
|
|
1623
1632
|
resolveSubgraphDb,
|
|
1624
1633
|
updateSubgraphStatus
|
|
1625
1634
|
} from "@secondlayer/shared/db/queries/subgraphs";
|
|
1626
|
-
import { logger as
|
|
1635
|
+
import { logger as logger6 } from "@secondlayer/shared/logger";
|
|
1627
1636
|
import { sql as sql3 } from "kysely";
|
|
1628
1637
|
|
|
1629
1638
|
// src/runtime/block-source.ts
|
|
@@ -1631,7 +1640,7 @@ import { getSourceDb as getSourceDb2 } from "@secondlayer/shared/db";
|
|
|
1631
1640
|
import {
|
|
1632
1641
|
IndexHttpClient
|
|
1633
1642
|
} from "@secondlayer/shared/index-http";
|
|
1634
|
-
import { logger as
|
|
1643
|
+
import { logger as logger4 } from "@secondlayer/shared/logger";
|
|
1635
1644
|
|
|
1636
1645
|
// src/runtime/batch-loader.ts
|
|
1637
1646
|
async function loadBlockRange(db, fromHeight, toHeight) {
|
|
@@ -1955,7 +1964,7 @@ class FallbackBlockSource {
|
|
|
1955
1964
|
try {
|
|
1956
1965
|
return await this.primary.getTip();
|
|
1957
1966
|
} catch (err) {
|
|
1958
|
-
|
|
1967
|
+
logger4.warn("block source primary getTip failed — using DB tap", {
|
|
1959
1968
|
error: err instanceof Error ? err.message : String(err)
|
|
1960
1969
|
});
|
|
1961
1970
|
return this.fallback.getTip();
|
|
@@ -1965,7 +1974,7 @@ class FallbackBlockSource {
|
|
|
1965
1974
|
try {
|
|
1966
1975
|
return await this.primary.loadBlockRange(fromHeight, toHeight);
|
|
1967
1976
|
} catch (err) {
|
|
1968
|
-
|
|
1977
|
+
logger4.warn("block source primary loadBlockRange failed — using DB tap", {
|
|
1969
1978
|
from: fromHeight,
|
|
1970
1979
|
to: toHeight,
|
|
1971
1980
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -1997,7 +2006,7 @@ function resolveBlockSource(subgraph) {
|
|
|
1997
2006
|
return new FallbackBlockSource(new PublicApiBlockSource(buildHttpClient(), referencedIndexEventTypes(subgraph), canSparseScan(subgraph) ? sparseProbeTargets(subgraph) : undefined, needsTransactionData(subgraph)), postgresBlockSource);
|
|
1998
2007
|
}
|
|
1999
2008
|
if (process.env.SUBGRAPH_SOURCE === "streams-index" && subgraph) {
|
|
2000
|
-
|
|
2009
|
+
logger4.debug("Subgraph not streams-index eligible, using DB tap", {
|
|
2001
2010
|
subgraph: subgraph.name
|
|
2002
2011
|
});
|
|
2003
2012
|
}
|
|
@@ -2006,7 +2015,7 @@ function resolveBlockSource(subgraph) {
|
|
|
2006
2015
|
|
|
2007
2016
|
// src/runtime/outbox-emit.ts
|
|
2008
2017
|
import { createHash as createHash2 } from "node:crypto";
|
|
2009
|
-
import { logger as
|
|
2018
|
+
import { logger as logger5 } from "@secondlayer/shared/logger";
|
|
2010
2019
|
var loggedKillSwitch = false;
|
|
2011
2020
|
var OP_VERB = {
|
|
2012
2021
|
insert: "created",
|
|
@@ -2030,7 +2039,7 @@ function stableStringify(obj) {
|
|
|
2030
2039
|
async function emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, blockHeight) {
|
|
2031
2040
|
if (!isEmitOutboxEnabled()) {
|
|
2032
2041
|
if (!loggedKillSwitch) {
|
|
2033
|
-
|
|
2042
|
+
logger5.warn("SECONDLAYER_EMIT_OUTBOX=false — outbox emission bypassed");
|
|
2034
2043
|
loggedKillSwitch = true;
|
|
2035
2044
|
}
|
|
2036
2045
|
return 0;
|
|
@@ -2350,7 +2359,7 @@ async function processBlockWithRetry(subgraph, subgraphName, blockHeight, opts,
|
|
|
2350
2359
|
const delay = retryDelaysMs[attempt];
|
|
2351
2360
|
if (delay === undefined)
|
|
2352
2361
|
break;
|
|
2353
|
-
|
|
2362
|
+
logger6.warn("Block processing failed, retrying", {
|
|
2354
2363
|
subgraph: subgraphName,
|
|
2355
2364
|
blockHeight,
|
|
2356
2365
|
attempt: attempt + 1,
|
|
@@ -2382,7 +2391,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2382
2391
|
} else {
|
|
2383
2392
|
const data = (await resolveBlockSource(subgraph).loadBlockRange(blockHeight, blockHeight)).get(blockHeight);
|
|
2384
2393
|
if (!data) {
|
|
2385
|
-
|
|
2394
|
+
logger6.debug("Block not found or non-canonical for subgraph processing", {
|
|
2386
2395
|
subgraph: subgraphName,
|
|
2387
2396
|
blockHeight
|
|
2388
2397
|
});
|
|
@@ -2523,7 +2532,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2523
2532
|
});
|
|
2524
2533
|
} catch (err) {
|
|
2525
2534
|
if (err instanceof CursorRaceLostError) {
|
|
2526
|
-
|
|
2535
|
+
logger6.warn("cursor race lost — block already covered", {
|
|
2527
2536
|
subgraph: subgraphName,
|
|
2528
2537
|
blockHeight,
|
|
2529
2538
|
error: err.message
|
|
@@ -2547,7 +2556,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2547
2556
|
const { rows } = await sql3.raw(`SELECT n_live_tup AS count FROM pg_stat_user_tables WHERE schemaname = '${schemaName}' AND relname = '${table}'`).execute(route.dataDb);
|
|
2548
2557
|
const count = Number(rows[0]?.count ?? 0);
|
|
2549
2558
|
if (count >= 1e7) {
|
|
2550
|
-
|
|
2559
|
+
logger6.warn("Subgraph table exceeds 10M rows (estimate)", {
|
|
2551
2560
|
subgraph: subgraphName,
|
|
2552
2561
|
table,
|
|
2553
2562
|
count
|
|
@@ -2555,7 +2564,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2555
2564
|
}
|
|
2556
2565
|
}
|
|
2557
2566
|
} catch (err) {
|
|
2558
|
-
|
|
2567
|
+
logger6.debug("Row count sample failed", {
|
|
2559
2568
|
subgraph: subgraphName,
|
|
2560
2569
|
error: err instanceof Error ? err.message : String(err)
|
|
2561
2570
|
});
|
|
@@ -2645,11 +2654,11 @@ import {
|
|
|
2645
2654
|
recordSubgraphProcessed as recordSubgraphProcessed2,
|
|
2646
2655
|
updateSubgraphStatus as updateSubgraphStatus2
|
|
2647
2656
|
} from "@secondlayer/shared/db/queries/subgraphs";
|
|
2648
|
-
import { logger as
|
|
2657
|
+
import { logger as logger8 } from "@secondlayer/shared/logger";
|
|
2649
2658
|
|
|
2650
2659
|
// src/runtime/reindex-notify.ts
|
|
2651
2660
|
import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
|
|
2652
|
-
import { logger as
|
|
2661
|
+
import { logger as logger7 } from "@secondlayer/shared/logger";
|
|
2653
2662
|
async function notifyReindexComplete(db, subgraphName, stats) {
|
|
2654
2663
|
try {
|
|
2655
2664
|
const subgraph = await db.selectFrom("subgraphs").select(["account_id"]).where("name", "=", subgraphName).executeTakeFirst();
|
|
@@ -2660,7 +2669,7 @@ async function notifyReindexComplete(db, subgraphName, stats) {
|
|
|
2660
2669
|
return;
|
|
2661
2670
|
const resendKey = process.env.RESEND_API_KEY;
|
|
2662
2671
|
if (!resendKey) {
|
|
2663
|
-
|
|
2672
|
+
logger7.warn("RESEND_API_KEY unset — skipping reindex-complete email", {
|
|
2664
2673
|
subgraph: subgraphName
|
|
2665
2674
|
});
|
|
2666
2675
|
return;
|
|
@@ -2682,14 +2691,14 @@ async function notifyReindexComplete(db, subgraphName, stats) {
|
|
|
2682
2691
|
});
|
|
2683
2692
|
if (!res.ok) {
|
|
2684
2693
|
const text = await res.text().catch(() => "");
|
|
2685
|
-
|
|
2694
|
+
logger7.warn("reindex-complete email failed", {
|
|
2686
2695
|
subgraph: subgraphName,
|
|
2687
2696
|
status: res.status,
|
|
2688
2697
|
body: text.slice(0, 200)
|
|
2689
2698
|
});
|
|
2690
2699
|
}
|
|
2691
2700
|
} catch (err) {
|
|
2692
|
-
|
|
2701
|
+
logger7.warn("reindex-complete email threw", {
|
|
2693
2702
|
subgraph: subgraphName,
|
|
2694
2703
|
error: getErrorMessage2(err)
|
|
2695
2704
|
});
|
|
@@ -2801,7 +2810,7 @@ async function processBlockRange(def, opts) {
|
|
|
2801
2810
|
while (currentHeight <= toBlock) {
|
|
2802
2811
|
if (opts.signal?.aborted) {
|
|
2803
2812
|
aborted = true;
|
|
2804
|
-
|
|
2813
|
+
logger8.info("Block processing aborted", {
|
|
2805
2814
|
subgraph: subgraphName,
|
|
2806
2815
|
currentBlock: currentHeight,
|
|
2807
2816
|
reason: String(opts.signal.reason ?? "unknown")
|
|
@@ -2850,7 +2859,7 @@ async function processBlockRange(def, opts) {
|
|
|
2850
2859
|
});
|
|
2851
2860
|
} catch (err) {
|
|
2852
2861
|
const errorMsg = getErrorMessage3(err);
|
|
2853
|
-
|
|
2862
|
+
logger8.error("Block processing failed persistently", {
|
|
2854
2863
|
subgraph: subgraphName,
|
|
2855
2864
|
blockHeight: height,
|
|
2856
2865
|
error: errorMsg
|
|
@@ -2896,7 +2905,7 @@ async function processBlockRange(def, opts) {
|
|
|
2896
2905
|
lastProgressFlushAt = now;
|
|
2897
2906
|
}
|
|
2898
2907
|
if (blocksProcessed % LOG_INTERVAL === 0) {
|
|
2899
|
-
|
|
2908
|
+
logger8.info(`${status === "reindexing" ? "Reindex" : "Backfill"} progress`, {
|
|
2900
2909
|
subgraph: subgraphName,
|
|
2901
2910
|
processed: blocksProcessed,
|
|
2902
2911
|
total: totalBlocks,
|
|
@@ -2916,7 +2925,7 @@ async function processBlockRange(def, opts) {
|
|
|
2916
2925
|
if (batchFailedBlocks.length > 0 && opts.subgraphId) {
|
|
2917
2926
|
const gaps = coalesceFailedBlocks(batchFailedBlocks);
|
|
2918
2927
|
await recordGapBatch(targetDb, opts.subgraphId, subgraphName, gaps).catch((err) => {
|
|
2919
|
-
|
|
2928
|
+
logger8.warn("Failed to record subgraph gaps", {
|
|
2920
2929
|
subgraph: subgraphName,
|
|
2921
2930
|
error: err instanceof Error ? err.message : String(err)
|
|
2922
2931
|
});
|
|
@@ -2933,7 +2942,7 @@ async function processBlockRange(def, opts) {
|
|
|
2933
2942
|
} else {
|
|
2934
2943
|
await updateSubgraphStatus2(targetDb, subgraphName, status, jumpTo - 1);
|
|
2935
2944
|
}
|
|
2936
|
-
|
|
2945
|
+
logger8.info("Sparse skip", {
|
|
2937
2946
|
subgraph: subgraphName,
|
|
2938
2947
|
from: batchEnd + 1,
|
|
2939
2948
|
to: jumpTo - 1,
|
|
@@ -2973,11 +2982,11 @@ async function reindexSubgraph(def, opts) {
|
|
|
2973
2982
|
const subgraphName = def.name;
|
|
2974
2983
|
const schemaName = opts?.schemaName ?? pgSchemaName(subgraphName);
|
|
2975
2984
|
await updateSubgraphStatus2(targetDb, subgraphName, "reindexing");
|
|
2976
|
-
|
|
2985
|
+
logger8.info("Reindex starting", { subgraph: subgraphName });
|
|
2977
2986
|
try {
|
|
2978
2987
|
const { fromBlock, toBlock } = await resolveBlockRange(source, def, opts);
|
|
2979
2988
|
if (fromBlock > toBlock) {
|
|
2980
|
-
|
|
2989
|
+
logger8.info("No blocks to reindex", {
|
|
2981
2990
|
subgraph: subgraphName,
|
|
2982
2991
|
fromBlock,
|
|
2983
2992
|
toBlock
|
|
@@ -2991,7 +3000,7 @@ async function reindexSubgraph(def, opts) {
|
|
|
2991
3000
|
await client.unsafe(stmt);
|
|
2992
3001
|
}
|
|
2993
3002
|
await updateSubgraphStatus2(targetDb, subgraphName, "reindexing", Math.max(0, fromBlock - 1));
|
|
2994
|
-
|
|
3003
|
+
logger8.info("Schema recreated for reindex", {
|
|
2995
3004
|
subgraph: subgraphName,
|
|
2996
3005
|
cursorResetTo: Math.max(0, fromBlock - 1)
|
|
2997
3006
|
});
|
|
@@ -3005,7 +3014,7 @@ async function reindexSubgraph(def, opts) {
|
|
|
3005
3014
|
last_error_at: null,
|
|
3006
3015
|
updated_at: new Date
|
|
3007
3016
|
}).where("name", "=", subgraphName).execute();
|
|
3008
|
-
|
|
3017
|
+
logger8.info("Reindexing blocks", {
|
|
3009
3018
|
subgraph: subgraphName,
|
|
3010
3019
|
fromBlock,
|
|
3011
3020
|
toBlock,
|
|
@@ -3027,9 +3036,9 @@ async function reindexSubgraph(def, opts) {
|
|
|
3027
3036
|
if (reason === "user-cancelled") {
|
|
3028
3037
|
await updateSubgraphStatus2(targetDb, subgraphName, "active");
|
|
3029
3038
|
await clearReindexMetadata(targetDb, subgraphName);
|
|
3030
|
-
|
|
3039
|
+
logger8.info("Reindex cancelled by user", { subgraph: subgraphName });
|
|
3031
3040
|
} else {
|
|
3032
|
-
|
|
3041
|
+
logger8.info("Reindex interrupted by shutdown, will resume", {
|
|
3033
3042
|
subgraph: subgraphName
|
|
3034
3043
|
});
|
|
3035
3044
|
}
|
|
@@ -3037,7 +3046,7 @@ async function reindexSubgraph(def, opts) {
|
|
|
3037
3046
|
}
|
|
3038
3047
|
await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
|
|
3039
3048
|
await clearReindexMetadata(targetDb, subgraphName);
|
|
3040
|
-
|
|
3049
|
+
logger8.info("Reindex complete", {
|
|
3041
3050
|
subgraph: subgraphName,
|
|
3042
3051
|
blocks: result.blocksProcessed,
|
|
3043
3052
|
events: result.totalEventsProcessed,
|
|
@@ -3050,7 +3059,7 @@ async function reindexSubgraph(def, opts) {
|
|
|
3050
3059
|
});
|
|
3051
3060
|
return { processed: result.blocksProcessed };
|
|
3052
3061
|
} catch (err) {
|
|
3053
|
-
|
|
3062
|
+
logger8.error("Reindex failed", {
|
|
3054
3063
|
subgraph: subgraphName,
|
|
3055
3064
|
error: getErrorMessage3(err)
|
|
3056
3065
|
});
|
|
@@ -3072,7 +3081,7 @@ async function resumeReindex(def, opts) {
|
|
|
3072
3081
|
const fromBlock = resolveReindexResumeBlock(row);
|
|
3073
3082
|
const toBlock = Number(row.reindex_to_block);
|
|
3074
3083
|
if (fromBlock == null) {
|
|
3075
|
-
|
|
3084
|
+
logger8.info("No reindex metadata, starting fresh reindex", {
|
|
3076
3085
|
subgraph: subgraphName
|
|
3077
3086
|
});
|
|
3078
3087
|
return reindexSubgraph(def, {
|
|
@@ -3081,12 +3090,12 @@ async function resumeReindex(def, opts) {
|
|
|
3081
3090
|
});
|
|
3082
3091
|
}
|
|
3083
3092
|
if (fromBlock > toBlock) {
|
|
3084
|
-
|
|
3093
|
+
logger8.info("Resume: no remaining blocks", { subgraph: subgraphName });
|
|
3085
3094
|
await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
|
|
3086
3095
|
await clearReindexMetadata(targetDb, subgraphName);
|
|
3087
3096
|
return { processed: 0 };
|
|
3088
3097
|
}
|
|
3089
|
-
|
|
3098
|
+
logger8.info("Resuming reindex", {
|
|
3090
3099
|
subgraph: subgraphName,
|
|
3091
3100
|
fromBlock,
|
|
3092
3101
|
toBlock,
|
|
@@ -3108,9 +3117,9 @@ async function resumeReindex(def, opts) {
|
|
|
3108
3117
|
if (reason === "user-cancelled") {
|
|
3109
3118
|
await updateSubgraphStatus2(targetDb, subgraphName, "active");
|
|
3110
3119
|
await clearReindexMetadata(targetDb, subgraphName);
|
|
3111
|
-
|
|
3120
|
+
logger8.info("Resume cancelled by user", { subgraph: subgraphName });
|
|
3112
3121
|
} else {
|
|
3113
|
-
|
|
3122
|
+
logger8.info("Resume interrupted by shutdown, will resume again", {
|
|
3114
3123
|
subgraph: subgraphName
|
|
3115
3124
|
});
|
|
3116
3125
|
}
|
|
@@ -3118,13 +3127,13 @@ async function resumeReindex(def, opts) {
|
|
|
3118
3127
|
}
|
|
3119
3128
|
await updateSubgraphStatus2(targetDb, subgraphName, "active", toBlock);
|
|
3120
3129
|
await clearReindexMetadata(targetDb, subgraphName);
|
|
3121
|
-
|
|
3130
|
+
logger8.info("Resumed reindex complete", {
|
|
3122
3131
|
subgraph: subgraphName,
|
|
3123
3132
|
blocks: result.blocksProcessed
|
|
3124
3133
|
});
|
|
3125
3134
|
return { processed: result.blocksProcessed };
|
|
3126
3135
|
} catch (err) {
|
|
3127
|
-
|
|
3136
|
+
logger8.error("Resumed reindex failed", {
|
|
3128
3137
|
subgraph: subgraphName,
|
|
3129
3138
|
error: getErrorMessage3(err)
|
|
3130
3139
|
});
|
|
@@ -3135,7 +3144,7 @@ async function resumeReindex(def, opts) {
|
|
|
3135
3144
|
async function backfillSubgraph(def, opts) {
|
|
3136
3145
|
const targetDb = getTargetDb2();
|
|
3137
3146
|
const subgraphName = def.name;
|
|
3138
|
-
|
|
3147
|
+
logger8.info("Backfill starting", {
|
|
3139
3148
|
subgraph: subgraphName,
|
|
3140
3149
|
from: opts.fromBlock,
|
|
3141
3150
|
to: opts.toBlock
|
|
@@ -3153,17 +3162,17 @@ async function backfillSubgraph(def, opts) {
|
|
|
3153
3162
|
signal: opts.signal
|
|
3154
3163
|
});
|
|
3155
3164
|
if (result.aborted) {
|
|
3156
|
-
|
|
3165
|
+
logger8.info("Backfill aborted", { subgraph: subgraphName });
|
|
3157
3166
|
return { processed: result.blocksProcessed };
|
|
3158
3167
|
}
|
|
3159
3168
|
const resolved = await resolveGaps(targetDb, subgraphName, opts.fromBlock, opts.toBlock).catch(() => 0);
|
|
3160
3169
|
if (resolved > 0) {
|
|
3161
|
-
|
|
3170
|
+
logger8.info("Resolved subgraph gaps via backfill", {
|
|
3162
3171
|
subgraph: subgraphName,
|
|
3163
3172
|
resolved
|
|
3164
3173
|
});
|
|
3165
3174
|
}
|
|
3166
|
-
|
|
3175
|
+
logger8.info("Backfill complete", {
|
|
3167
3176
|
subgraph: subgraphName,
|
|
3168
3177
|
blocks: result.blocksProcessed,
|
|
3169
3178
|
events: result.totalEventsProcessed,
|
|
@@ -3171,7 +3180,7 @@ async function backfillSubgraph(def, opts) {
|
|
|
3171
3180
|
});
|
|
3172
3181
|
return { processed: result.blocksProcessed };
|
|
3173
3182
|
} catch (err) {
|
|
3174
|
-
|
|
3183
|
+
logger8.error("Backfill failed", {
|
|
3175
3184
|
subgraph: subgraphName,
|
|
3176
3185
|
error: getErrorMessage3(err)
|
|
3177
3186
|
});
|
|
@@ -3182,7 +3191,7 @@ async function backfillSubgraph(def, opts) {
|
|
|
3182
3191
|
// src/runtime/catchup.ts
|
|
3183
3192
|
import { getTargetDb as getTargetDb3 } from "@secondlayer/shared/db";
|
|
3184
3193
|
import { getSubgraph } from "@secondlayer/shared/db/queries/subgraphs";
|
|
3185
|
-
import { logger as
|
|
3194
|
+
import { logger as logger9 } from "@secondlayer/shared/logger";
|
|
3186
3195
|
var LOG_INTERVAL2 = 1000;
|
|
3187
3196
|
var STANDARD_CATCHUP_BATCH_CONFIG = {
|
|
3188
3197
|
defaultBatchSize: 500,
|
|
@@ -3289,7 +3298,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3289
3298
|
const subgraphStart = Number(subgraphRow.start_block) || 1;
|
|
3290
3299
|
const startBlock = Math.max(lastProcessedBlock + 1, subgraphStart);
|
|
3291
3300
|
const totalBlocks = chainTip - lastProcessedBlock;
|
|
3292
|
-
|
|
3301
|
+
logger9.info("Subgraph catch-up starting", {
|
|
3293
3302
|
subgraph: subgraphName,
|
|
3294
3303
|
from: startBlock,
|
|
3295
3304
|
to: chainTip,
|
|
@@ -3306,7 +3315,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3306
3315
|
while (currentHeight <= chainTip) {
|
|
3307
3316
|
const currentRow = await getSubgraph(targetDb, subgraphName);
|
|
3308
3317
|
if (!currentRow || currentRow.status !== "active") {
|
|
3309
|
-
|
|
3318
|
+
logger9.info("Subgraph status changed, stopping catch-up", {
|
|
3310
3319
|
subgraph: subgraphName,
|
|
3311
3320
|
status: currentRow?.status ?? "deleted"
|
|
3312
3321
|
});
|
|
@@ -3335,7 +3344,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3335
3344
|
blockData = (await source.loadBlockRange(height, height)).get(height);
|
|
3336
3345
|
}
|
|
3337
3346
|
if (!blockData) {
|
|
3338
|
-
|
|
3347
|
+
logger9.warn("Block missing during catch-up, deferring to next tick", {
|
|
3339
3348
|
subgraph: subgraphName,
|
|
3340
3349
|
blockHeight: height
|
|
3341
3350
|
});
|
|
@@ -3355,12 +3364,12 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3355
3364
|
});
|
|
3356
3365
|
} catch (err) {
|
|
3357
3366
|
if (err instanceof ReorgEpochChangedError) {
|
|
3358
|
-
|
|
3367
|
+
logger9.info("Reorg detected mid catch-up, aborting walk without writing further progress", { subgraph: subgraphName, blockHeight: height });
|
|
3359
3368
|
stopCatchup = true;
|
|
3360
3369
|
break;
|
|
3361
3370
|
}
|
|
3362
3371
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
3363
|
-
|
|
3372
|
+
logger9.error("Block processing failed persistently during catch-up", {
|
|
3364
3373
|
subgraph: subgraphName,
|
|
3365
3374
|
blockHeight: height,
|
|
3366
3375
|
error: errorMsg
|
|
@@ -3379,7 +3388,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3379
3388
|
}
|
|
3380
3389
|
}
|
|
3381
3390
|
if (processed % LOG_INTERVAL2 === 0) {
|
|
3382
|
-
|
|
3391
|
+
logger9.info("Subgraph catch-up progress", {
|
|
3383
3392
|
subgraph: subgraphName,
|
|
3384
3393
|
processed,
|
|
3385
3394
|
total: totalBlocks,
|
|
@@ -3395,7 +3404,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3395
3404
|
currentHeight = batchEnd + 1;
|
|
3396
3405
|
}
|
|
3397
3406
|
await stats.flush(targetDb);
|
|
3398
|
-
|
|
3407
|
+
logger9.info("Subgraph catch-up complete", {
|
|
3399
3408
|
subgraph: subgraphName,
|
|
3400
3409
|
processed
|
|
3401
3410
|
});
|
|
@@ -3412,13 +3421,13 @@ import {
|
|
|
3412
3421
|
listSubgraphs,
|
|
3413
3422
|
resolveSubgraphRawClient
|
|
3414
3423
|
} from "@secondlayer/shared/db/queries/subgraphs";
|
|
3415
|
-
import { logger as
|
|
3424
|
+
import { logger as logger10 } from "@secondlayer/shared/logger";
|
|
3416
3425
|
async function handleSubgraphReorg(blockHeight, loadSubgraphDef) {
|
|
3417
3426
|
const targetDb = getTargetDb4();
|
|
3418
3427
|
const activeSubgraphs = (await listSubgraphs(targetDb)).filter((v) => v.status === "active");
|
|
3419
3428
|
if (activeSubgraphs.length === 0)
|
|
3420
3429
|
return;
|
|
3421
|
-
|
|
3430
|
+
logger10.info("Propagating reorg to subgraphs", {
|
|
3422
3431
|
blockHeight,
|
|
3423
3432
|
subgraphCount: activeSubgraphs.length
|
|
3424
3433
|
});
|
|
@@ -3457,7 +3466,7 @@ async function handleSubgraphReorg(blockHeight, loadSubgraphDef) {
|
|
|
3457
3466
|
await tx.unsafe(`DELETE FROM "${schemaName}"."_journal" WHERE block_height >= $1`, [blockHeight]);
|
|
3458
3467
|
});
|
|
3459
3468
|
} else {
|
|
3460
|
-
|
|
3469
|
+
logger10.warn("Subgraph has no revert journal — falling back to height delete (accumulator rows may lose history)", { subgraph: sg.name, blockHeight });
|
|
3461
3470
|
for (const tableName of tableNames) {
|
|
3462
3471
|
await client.unsafe(`DELETE FROM "${schemaName}"."${tableName}" WHERE "_block_height" >= $1`, [blockHeight]);
|
|
3463
3472
|
}
|
|
@@ -3500,7 +3509,7 @@ async function handleSubgraphReorg(blockHeight, loadSubgraphDef) {
|
|
|
3500
3509
|
}).as("row_pk"),
|
|
3501
3510
|
eb2.val("pending").as("status")
|
|
3502
3511
|
]).where("subgraph_name", "=", sg.name).where("table_name", "=", tableName).where("status", "=", "active")).onConflict((oc) => oc.columns(["subscription_id", "dedup_key"]).doNothing()).execute().catch((err) => {
|
|
3503
|
-
|
|
3512
|
+
logger10.error("Failed to emit revert event for subscriptions", {
|
|
3504
3513
|
event: "reorg_revert_emit_dropped",
|
|
3505
3514
|
subgraph: sg.name,
|
|
3506
3515
|
table: tableName,
|
|
@@ -3509,20 +3518,20 @@ async function handleSubgraphReorg(blockHeight, loadSubgraphDef) {
|
|
|
3509
3518
|
});
|
|
3510
3519
|
});
|
|
3511
3520
|
}
|
|
3512
|
-
|
|
3521
|
+
logger10.info("Subgraph reorg cleanup done", {
|
|
3513
3522
|
subgraph: sg.name,
|
|
3514
3523
|
blockHeight,
|
|
3515
3524
|
tablesAffected: Object.keys(revertedByTable).length
|
|
3516
3525
|
});
|
|
3517
3526
|
const def = await loadSubgraphDef(sg);
|
|
3518
3527
|
await processBlock(def, sg.name, blockHeight);
|
|
3519
|
-
|
|
3528
|
+
logger10.info("Subgraph reorg reprocessed", {
|
|
3520
3529
|
subgraph: sg.name,
|
|
3521
3530
|
blockHeight
|
|
3522
3531
|
});
|
|
3523
3532
|
});
|
|
3524
3533
|
} catch (err) {
|
|
3525
|
-
|
|
3534
|
+
logger10.error("Subgraph reorg handling failed", {
|
|
3526
3535
|
subgraph: sg.name,
|
|
3527
3536
|
blockHeight,
|
|
3528
3537
|
error: getErrorMessage4(err)
|
|
@@ -3555,7 +3564,7 @@ import {
|
|
|
3555
3564
|
pgSchemaName as pgSchemaName2,
|
|
3556
3565
|
updateSubgraphStatus as updateSubgraphStatus3
|
|
3557
3566
|
} from "@secondlayer/shared/db/queries/subgraphs";
|
|
3558
|
-
import { logger as
|
|
3567
|
+
import { logger as logger12 } from "@secondlayer/shared/logger";
|
|
3559
3568
|
import {
|
|
3560
3569
|
listen,
|
|
3561
3570
|
sourceListenerUrl,
|
|
@@ -3590,7 +3599,7 @@ function startCatchUpLeader(opts = {}) {
|
|
|
3590
3599
|
// src/runtime/streams-reorg-poll.ts
|
|
3591
3600
|
import { getErrorMessage as getErrorMessage5 } from "@secondlayer/shared";
|
|
3592
3601
|
import { IndexHttpClient as IndexHttpClient2 } from "@secondlayer/shared/index-http";
|
|
3593
|
-
import { logger as
|
|
3602
|
+
import { logger as logger11 } from "@secondlayer/shared/logger";
|
|
3594
3603
|
var POLL_MS = Number(process.env.SUBGRAPH_REORG_POLL_MS) || 15000;
|
|
3595
3604
|
var STARTUP_MARGIN_MS = 60 * 60 * 1000;
|
|
3596
3605
|
async function pollReorgsOnce(http2, cursor, onReorg, handled) {
|
|
@@ -3598,13 +3607,13 @@ async function pollReorgsOnce(http2, cursor, onReorg, handled) {
|
|
|
3598
3607
|
const sorted = [...reorgs].sort((a, b) => a.fork_point_height - b.fork_point_height);
|
|
3599
3608
|
for (const r of sorted) {
|
|
3600
3609
|
if (handled && r.id && handled.has(r.id)) {
|
|
3601
|
-
|
|
3610
|
+
logger11.info("Streams reorg already handled — skipping", {
|
|
3602
3611
|
forkPointHeight: r.fork_point_height,
|
|
3603
3612
|
reorgId: r.id
|
|
3604
3613
|
});
|
|
3605
3614
|
continue;
|
|
3606
3615
|
}
|
|
3607
|
-
|
|
3616
|
+
logger11.info("Streams reorg — rewinding", {
|
|
3608
3617
|
forkPointHeight: r.fork_point_height
|
|
3609
3618
|
});
|
|
3610
3619
|
await onReorg(r.fork_point_height);
|
|
@@ -3632,7 +3641,7 @@ function startStreamsReorgPoll(onReorg) {
|
|
|
3632
3641
|
try {
|
|
3633
3642
|
since = await pollReorgsOnce(http2, since, onReorg, handled);
|
|
3634
3643
|
} catch (err) {
|
|
3635
|
-
|
|
3644
|
+
logger11.error("Streams reorg poll failed", {
|
|
3636
3645
|
error: getErrorMessage5(err)
|
|
3637
3646
|
});
|
|
3638
3647
|
}
|
|
@@ -3640,7 +3649,7 @@ function startStreamsReorgPoll(onReorg) {
|
|
|
3640
3649
|
timer = setTimeout(tick, POLL_MS);
|
|
3641
3650
|
};
|
|
3642
3651
|
timer = setTimeout(tick, POLL_MS);
|
|
3643
|
-
|
|
3652
|
+
logger11.info("Streams reorg poll started", { pollMs: POLL_MS });
|
|
3644
3653
|
return () => {
|
|
3645
3654
|
running = false;
|
|
3646
3655
|
if (timer)
|
|
@@ -3671,7 +3680,7 @@ async function catchUpAll(subgraphs, db, concurrency) {
|
|
|
3671
3680
|
if (isHandlerNotFoundError(err)) {
|
|
3672
3681
|
await updateSubgraphStatus3(db, sg.name, "error");
|
|
3673
3682
|
}
|
|
3674
|
-
|
|
3683
|
+
logger12.error("Subgraph catch-up failed", {
|
|
3675
3684
|
subgraph: sg.name,
|
|
3676
3685
|
error: msg
|
|
3677
3686
|
});
|
|
@@ -3711,7 +3720,7 @@ async function loadSubgraphDefinition(sg) {
|
|
|
3711
3720
|
definitionCache.set(sg.name, def);
|
|
3712
3721
|
if (prevVersion && prevVersion !== sg.version) {
|
|
3713
3722
|
invalidateSubgraphRoute(sg.name);
|
|
3714
|
-
|
|
3723
|
+
logger12.info("Subgraph handler reloaded", {
|
|
3715
3724
|
subgraph: sg.name,
|
|
3716
3725
|
from: prevVersion,
|
|
3717
3726
|
to: sg.version
|
|
@@ -3745,7 +3754,7 @@ async function synthesizeLegacyReindexOperations() {
|
|
|
3745
3754
|
fromBlock: sg.reindex_from_block == null ? undefined : Number(sg.reindex_from_block),
|
|
3746
3755
|
toBlock: sg.reindex_to_block == null ? undefined : Number(sg.reindex_to_block)
|
|
3747
3756
|
});
|
|
3748
|
-
|
|
3757
|
+
logger12.info("Queued legacy reindex resume operation", {
|
|
3749
3758
|
subgraph: sg.name
|
|
3750
3759
|
});
|
|
3751
3760
|
} catch (err) {
|
|
@@ -3808,7 +3817,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3808
3817
|
const activeRuns = new Map;
|
|
3809
3818
|
let running = true;
|
|
3810
3819
|
let draining = false;
|
|
3811
|
-
|
|
3820
|
+
logger12.info("Starting subgraph operation runner", { concurrency, lockedBy });
|
|
3812
3821
|
try {
|
|
3813
3822
|
const stranded = await db.selectFrom("subgraphs").select(["id", "name", "account_id"]).where("status", "=", "reindexing").where("reindex_from_block", "is not", null).where("reindex_to_block", "is not", null).where(({ not, exists, selectFrom }) => not(exists(selectFrom("subgraph_operations").select("id").whereRef("subgraph_id", "=", "subgraphs.id").where("status", "in", ["queued", "running"])))).execute();
|
|
3814
3823
|
for (const row of stranded) {
|
|
@@ -3819,14 +3828,14 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3819
3828
|
accountId: row.account_id,
|
|
3820
3829
|
kind: "reindex"
|
|
3821
3830
|
});
|
|
3822
|
-
|
|
3831
|
+
logger12.info("Re-enqueued stranded reindex", { subgraph: row.name });
|
|
3823
3832
|
} catch (err) {
|
|
3824
3833
|
if (!isActiveSubgraphOperationConflict(err))
|
|
3825
3834
|
throw err;
|
|
3826
3835
|
}
|
|
3827
3836
|
}
|
|
3828
3837
|
} catch (err) {
|
|
3829
|
-
|
|
3838
|
+
logger12.warn("Stranded-reindex sweep failed", {
|
|
3830
3839
|
error: getErrorMessage6(err)
|
|
3831
3840
|
});
|
|
3832
3841
|
}
|
|
@@ -3837,7 +3846,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3837
3846
|
if (!running)
|
|
3838
3847
|
return;
|
|
3839
3848
|
heartbeatSubgraphOperation(db, operation.id, lockedBy).catch((err) => {
|
|
3840
|
-
|
|
3849
|
+
logger12.warn("Subgraph operation heartbeat failed", {
|
|
3841
3850
|
operationId: operation.id,
|
|
3842
3851
|
error: getErrorMessage6(err)
|
|
3843
3852
|
});
|
|
@@ -3849,7 +3858,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3849
3858
|
controller.abort("user-cancelled");
|
|
3850
3859
|
}
|
|
3851
3860
|
}).catch((err) => {
|
|
3852
|
-
|
|
3861
|
+
logger12.warn("Subgraph operation cancel poll failed", {
|
|
3853
3862
|
operationId: operation.id,
|
|
3854
3863
|
error: getErrorMessage6(err)
|
|
3855
3864
|
});
|
|
@@ -3866,14 +3875,14 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3866
3875
|
const reason = String(controller.signal.reason ?? "");
|
|
3867
3876
|
if (controller.signal.aborted && reason === "user-cancelled") {
|
|
3868
3877
|
await cancelSubgraphOperation(db, operation.id, lockedBy, processed);
|
|
3869
|
-
|
|
3878
|
+
logger12.info("Subgraph operation cancelled", {
|
|
3870
3879
|
operationId: operation.id,
|
|
3871
3880
|
subgraph: operation.subgraph_name
|
|
3872
3881
|
});
|
|
3873
3882
|
return;
|
|
3874
3883
|
}
|
|
3875
3884
|
if (controller.signal.aborted) {
|
|
3876
|
-
|
|
3885
|
+
logger12.info("Subgraph operation interrupted", {
|
|
3877
3886
|
operationId: operation.id,
|
|
3878
3887
|
subgraph: operation.subgraph_name,
|
|
3879
3888
|
reason
|
|
@@ -3881,7 +3890,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3881
3890
|
return;
|
|
3882
3891
|
}
|
|
3883
3892
|
await completeSubgraphOperation(db, operation.id, lockedBy, processed);
|
|
3884
|
-
|
|
3893
|
+
logger12.info("Subgraph operation completed", {
|
|
3885
3894
|
operationId: operation.id,
|
|
3886
3895
|
subgraph: operation.subgraph_name,
|
|
3887
3896
|
processed
|
|
@@ -3889,7 +3898,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3889
3898
|
} catch (err) {
|
|
3890
3899
|
const reason = String(controller.signal.reason ?? "");
|
|
3891
3900
|
if (controller.signal.aborted && reason === "shutdown") {
|
|
3892
|
-
|
|
3901
|
+
logger12.info("Subgraph operation interrupted by shutdown", {
|
|
3893
3902
|
operationId: operation.id,
|
|
3894
3903
|
subgraph: operation.subgraph_name
|
|
3895
3904
|
});
|
|
@@ -3900,7 +3909,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3900
3909
|
return;
|
|
3901
3910
|
}
|
|
3902
3911
|
await failSubgraphOperation(db, operation.id, lockedBy, getErrorMessage6(err), processed);
|
|
3903
|
-
|
|
3912
|
+
logger12.error("Subgraph operation failed", {
|
|
3904
3913
|
operationId: operation.id,
|
|
3905
3914
|
subgraph: operation.subgraph_name,
|
|
3906
3915
|
error: getErrorMessage6(err)
|
|
@@ -3947,13 +3956,13 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
3947
3956
|
controller.abort("shutdown");
|
|
3948
3957
|
}
|
|
3949
3958
|
await Promise.allSettled(activeRuns.values());
|
|
3950
|
-
|
|
3959
|
+
logger12.info("Subgraph operation runner stopped");
|
|
3951
3960
|
};
|
|
3952
3961
|
}
|
|
3953
3962
|
async function startSubgraphProcessor(opts) {
|
|
3954
3963
|
const concurrency = opts?.concurrency ?? DEFAULT_CONCURRENCY;
|
|
3955
3964
|
let running = true;
|
|
3956
|
-
|
|
3965
|
+
logger12.info("Starting subgraph processor", { concurrency });
|
|
3957
3966
|
const stopOperations = await startSubgraphOperationRunner({
|
|
3958
3967
|
concurrency: Number.parseInt(process.env.SUBGRAPH_OPERATION_CONCURRENCY ?? String(DEFAULT_OPERATION_CONCURRENCY))
|
|
3959
3968
|
});
|
|
@@ -3979,7 +3988,7 @@ async function startSubgraphProcessor(opts) {
|
|
|
3979
3988
|
await handleSubgraphReorg(blockHeight, loadSubgraphDefinition);
|
|
3980
3989
|
}
|
|
3981
3990
|
} catch (err) {
|
|
3982
|
-
|
|
3991
|
+
logger12.error("Subgraph reorg handling failed", {
|
|
3983
3992
|
error: getErrorMessage6(err)
|
|
3984
3993
|
});
|
|
3985
3994
|
}
|
|
@@ -3988,7 +3997,7 @@ async function startSubgraphProcessor(opts) {
|
|
|
3988
3997
|
runCatchUp();
|
|
3989
3998
|
}, POLL_INTERVAL_MS);
|
|
3990
3999
|
const stopStreamsReorgPoll = process.env.SUBGRAPH_SOURCE === "streams-index" ? startStreamsReorgPoll((forkHeight) => handleSubgraphReorg(forkHeight, loadSubgraphDefinition)) : undefined;
|
|
3991
|
-
|
|
4000
|
+
logger12.info("Subgraph processor ready");
|
|
3992
4001
|
return async () => {
|
|
3993
4002
|
running = false;
|
|
3994
4003
|
clearInterval(pollInterval);
|
|
@@ -3997,13 +4006,13 @@ async function startSubgraphProcessor(opts) {
|
|
|
3997
4006
|
await stopReorgListening();
|
|
3998
4007
|
stopStreamsReorgPoll?.();
|
|
3999
4008
|
await stopOperations();
|
|
4000
|
-
|
|
4009
|
+
logger12.info("Subgraph processor stopped");
|
|
4001
4010
|
};
|
|
4002
4011
|
}
|
|
4003
4012
|
|
|
4004
4013
|
// src/service.ts
|
|
4005
4014
|
import { assertDbSplit, getDb } from "@secondlayer/shared/db";
|
|
4006
|
-
import { logger as
|
|
4015
|
+
import { logger as logger13 } from "@secondlayer/shared/logger";
|
|
4007
4016
|
import { sql as sql4 } from "kysely";
|
|
4008
4017
|
var HEARTBEAT_INTERVAL_MS2 = 30000;
|
|
4009
4018
|
var SERVICE_NAME = "subgraph-processor";
|
|
@@ -4011,7 +4020,7 @@ async function writeHeartbeat() {
|
|
|
4011
4020
|
try {
|
|
4012
4021
|
await getDb().insertInto("service_heartbeats").values({ name: SERVICE_NAME }).onConflict((oc) => oc.column("name").doUpdateSet({ updated_at: sql4`now()` })).execute();
|
|
4013
4022
|
} catch (err) {
|
|
4014
|
-
|
|
4023
|
+
logger13.warn("subgraph-processor heartbeat write failed", {
|
|
4015
4024
|
error: err instanceof Error ? err.message : String(err)
|
|
4016
4025
|
});
|
|
4017
4026
|
}
|
|
@@ -4023,7 +4032,7 @@ var processor = await startSubgraphProcessor({
|
|
|
4023
4032
|
await writeHeartbeat();
|
|
4024
4033
|
var heartbeatInterval = setInterval(writeHeartbeat, HEARTBEAT_INTERVAL_MS2);
|
|
4025
4034
|
var shutdown = async () => {
|
|
4026
|
-
|
|
4035
|
+
logger13.info("Shutting down subgraph processor...");
|
|
4027
4036
|
clearInterval(heartbeatInterval);
|
|
4028
4037
|
await processor();
|
|
4029
4038
|
process.exit(0);
|
|
@@ -4031,5 +4040,5 @@ var shutdown = async () => {
|
|
|
4031
4040
|
process.on("SIGINT", shutdown);
|
|
4032
4041
|
process.on("SIGTERM", shutdown);
|
|
4033
4042
|
|
|
4034
|
-
//# debugId=
|
|
4043
|
+
//# debugId=3C956FA29EC3292A64756E2164756E21
|
|
4035
4044
|
//# sourceMappingURL=service.js.map
|