@secondlayer/subgraphs 1.3.1 → 1.3.3
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/README.md +1 -1
- package/dist/src/index.js +22 -11
- package/dist/src/index.js.map +8 -8
- package/dist/src/runtime/block-processor.js +4 -4
- package/dist/src/runtime/block-processor.js.map +5 -5
- package/dist/src/runtime/catchup.d.ts +16 -2
- package/dist/src/runtime/catchup.js +68 -20
- package/dist/src/runtime/catchup.js.map +6 -6
- package/dist/src/runtime/context.js +4 -4
- package/dist/src/runtime/context.js.map +3 -3
- package/dist/src/runtime/processor.js +87 -31
- package/dist/src/runtime/processor.js.map +13 -13
- package/dist/src/runtime/reindex.js +22 -11
- package/dist/src/runtime/reindex.js.map +7 -7
- package/dist/src/runtime/reorg.js +4 -4
- package/dist/src/runtime/reorg.js.map +5 -5
- package/dist/src/schema/index.js +6 -6
- package/dist/src/schema/index.js.map +4 -4
- package/dist/src/service.js +87 -31
- package/dist/src/service.js.map +13 -13
- package/dist/src/validate.js.map +2 -2
- package/package.json +3 -3
package/dist/src/service.js
CHANGED
|
@@ -187,9 +187,9 @@ class SubgraphContext {
|
|
|
187
187
|
const blockHeight = op.data._block_height ?? this.block.height;
|
|
188
188
|
const txId = op.data._tx_id ?? this._tx.txId;
|
|
189
189
|
const baseRow = op.kind === "update" ? { ...op.data, ...op.set ?? {} } : { ...op.data };
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
baseRow._upsert_keys = undefined;
|
|
191
|
+
baseRow._upsert_fallback_keys = undefined;
|
|
192
|
+
baseRow._upsert_fallback_set = undefined;
|
|
193
193
|
return {
|
|
194
194
|
op: op.kind,
|
|
195
195
|
table: op.table,
|
|
@@ -1336,16 +1336,16 @@ function generateSubgraphSQL(def, schemaNameOverride) {
|
|
|
1336
1336
|
const statements = [];
|
|
1337
1337
|
const needsTrgm = Object.values(def.schema).some((table) => Object.values(table.columns).some((col) => col.search));
|
|
1338
1338
|
if (needsTrgm) {
|
|
1339
|
-
statements.push(
|
|
1339
|
+
statements.push("CREATE EXTENSION IF NOT EXISTS pg_trgm");
|
|
1340
1340
|
}
|
|
1341
1341
|
statements.push(`CREATE SCHEMA IF NOT EXISTS ${schemaName}`);
|
|
1342
1342
|
for (const [tableName, tableDef] of Object.entries(def.schema)) {
|
|
1343
1343
|
const qualifiedName = `${schemaName}.${tableName}`;
|
|
1344
1344
|
const columnDefs = [
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1345
|
+
"_id BIGSERIAL PRIMARY KEY",
|
|
1346
|
+
"_block_height BIGINT NOT NULL",
|
|
1347
|
+
"_tx_id TEXT NOT NULL",
|
|
1348
|
+
"_created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()"
|
|
1349
1349
|
];
|
|
1350
1350
|
for (const [colName, col] of Object.entries(tableDef.columns)) {
|
|
1351
1351
|
const sqlType = TYPE_MAP[col.type];
|
|
@@ -1441,6 +1441,7 @@ function avgEventsPerBlock(batch) {
|
|
|
1441
1441
|
// src/runtime/reindex.ts
|
|
1442
1442
|
var LOG_INTERVAL = 1000;
|
|
1443
1443
|
var HEALTH_FLUSH_INTERVAL = 1000;
|
|
1444
|
+
var PROGRESS_FLUSH_INTERVAL_MS = 5000;
|
|
1444
1445
|
var HOBBY_REINDEX_BATCH_CONFIG = {
|
|
1445
1446
|
defaultBatchSize: 50,
|
|
1446
1447
|
minBatchSize: 25,
|
|
@@ -1515,6 +1516,8 @@ async function processBlockRange(def, opts) {
|
|
|
1515
1516
|
let pendingErrors = 0;
|
|
1516
1517
|
let pendingLastError;
|
|
1517
1518
|
let lastHealthFlushBlock = 0;
|
|
1519
|
+
let lastHealthFlushAt = Date.now();
|
|
1520
|
+
let lastProgressFlushAt = Date.now();
|
|
1518
1521
|
const batchConfig = resolveReindexBatchConfig();
|
|
1519
1522
|
let batchSize = batchConfig.defaultBatchSize;
|
|
1520
1523
|
let currentHeight = fromBlock;
|
|
@@ -1527,6 +1530,7 @@ async function processBlockRange(def, opts) {
|
|
|
1527
1530
|
pendingErrors = 0;
|
|
1528
1531
|
pendingLastError = undefined;
|
|
1529
1532
|
lastHealthFlushBlock = blocksProcessed;
|
|
1533
|
+
lastHealthFlushAt = Date.now();
|
|
1530
1534
|
};
|
|
1531
1535
|
let nextBatchEnd = Math.min(currentHeight + batchSize - 1, toBlock);
|
|
1532
1536
|
let nextBatchPromise = loadBlockRange(sourceDb, currentHeight, nextBatchEnd);
|
|
@@ -1590,8 +1594,11 @@ async function processBlockRange(def, opts) {
|
|
|
1590
1594
|
await stats.flush(targetDb);
|
|
1591
1595
|
}
|
|
1592
1596
|
}
|
|
1593
|
-
|
|
1597
|
+
const now = Date.now();
|
|
1598
|
+
const shouldFlushProgress = blocksProcessed % 100 === 0 || now - lastProgressFlushAt >= PROGRESS_FLUSH_INTERVAL_MS;
|
|
1599
|
+
if (shouldFlushProgress) {
|
|
1594
1600
|
await updateSubgraphStatus2(targetDb, subgraphName, status, height);
|
|
1601
|
+
lastProgressFlushAt = now;
|
|
1595
1602
|
}
|
|
1596
1603
|
if (blocksProcessed % LOG_INTERVAL === 0) {
|
|
1597
1604
|
logger5.info(`${status === "reindexing" ? "Reindex" : "Backfill"} progress`, {
|
|
@@ -1603,7 +1610,11 @@ async function processBlockRange(def, opts) {
|
|
|
1603
1610
|
});
|
|
1604
1611
|
}
|
|
1605
1612
|
}
|
|
1606
|
-
if (
|
|
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) {
|
|
1607
1618
|
await flushHealth();
|
|
1608
1619
|
}
|
|
1609
1620
|
if (batchFailedBlocks.length > 0 && opts.subgraphId) {
|
|
@@ -1849,10 +1860,47 @@ import {
|
|
|
1849
1860
|
import { getSubgraph } from "@secondlayer/shared/db/queries/subgraphs";
|
|
1850
1861
|
import { logger as logger6 } from "@secondlayer/shared/logger";
|
|
1851
1862
|
var LOG_INTERVAL2 = 1000;
|
|
1852
|
-
var
|
|
1853
|
-
|
|
1854
|
-
|
|
1863
|
+
var HOBBY_CATCHUP_BATCH_CONFIG = {
|
|
1864
|
+
defaultBatchSize: 50,
|
|
1865
|
+
minBatchSize: 25,
|
|
1866
|
+
maxBatchSize: 100,
|
|
1867
|
+
prefetch: false
|
|
1868
|
+
};
|
|
1869
|
+
var STANDARD_CATCHUP_BATCH_CONFIG = {
|
|
1870
|
+
defaultBatchSize: 500,
|
|
1871
|
+
minBatchSize: 100,
|
|
1872
|
+
maxBatchSize: 1000,
|
|
1873
|
+
prefetch: true
|
|
1874
|
+
};
|
|
1855
1875
|
var catchingUp = new Set;
|
|
1876
|
+
function parsePositiveInt2(value) {
|
|
1877
|
+
if (value == null || value.trim() === "")
|
|
1878
|
+
return;
|
|
1879
|
+
const parsed = Number.parseInt(value, 10);
|
|
1880
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
1881
|
+
}
|
|
1882
|
+
function parseBoolean(value) {
|
|
1883
|
+
if (value == null || value.trim() === "")
|
|
1884
|
+
return;
|
|
1885
|
+
const normalized = value.trim().toLowerCase();
|
|
1886
|
+
if (normalized === "true")
|
|
1887
|
+
return true;
|
|
1888
|
+
if (normalized === "false")
|
|
1889
|
+
return false;
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
function resolveCatchupBatchConfig(env = process.env) {
|
|
1893
|
+
const base = env.TENANT_PLAN?.trim().toLowerCase() === "hobby" ? HOBBY_CATCHUP_BATCH_CONFIG : STANDARD_CATCHUP_BATCH_CONFIG;
|
|
1894
|
+
const minBatchSize = parsePositiveInt2(env.SUBGRAPH_CATCHUP_MIN_BATCH_SIZE) ?? base.minBatchSize;
|
|
1895
|
+
const maxBatchSize = parsePositiveInt2(env.SUBGRAPH_CATCHUP_MAX_BATCH_SIZE) ?? base.maxBatchSize;
|
|
1896
|
+
const defaultBatchSize = parsePositiveInt2(env.SUBGRAPH_CATCHUP_BATCH_SIZE) ?? base.defaultBatchSize;
|
|
1897
|
+
return {
|
|
1898
|
+
minBatchSize,
|
|
1899
|
+
maxBatchSize,
|
|
1900
|
+
defaultBatchSize: Math.min(Math.max(defaultBatchSize, minBatchSize), maxBatchSize),
|
|
1901
|
+
prefetch: parseBoolean(env.SUBGRAPH_CATCHUP_PREFETCH) ?? base.prefetch
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1856
1904
|
function coalesceGaps(blocks) {
|
|
1857
1905
|
if (blocks.length === 0)
|
|
1858
1906
|
return [];
|
|
@@ -1875,11 +1923,11 @@ function coalesceGaps(blocks) {
|
|
|
1875
1923
|
ranges.push({ start, end, reason });
|
|
1876
1924
|
return ranges;
|
|
1877
1925
|
}
|
|
1878
|
-
function adjustBatchSize(current, avgEvents) {
|
|
1926
|
+
function adjustBatchSize(current, avgEvents, config) {
|
|
1879
1927
|
if (avgEvents > 50)
|
|
1880
|
-
return Math.max(Math.round(current * 0.5),
|
|
1928
|
+
return Math.max(Math.round(current * 0.5), config.minBatchSize);
|
|
1881
1929
|
if (avgEvents < 10)
|
|
1882
|
-
return Math.min(Math.round(current * 1.5),
|
|
1930
|
+
return Math.min(Math.round(current * 1.5), config.maxBatchSize);
|
|
1883
1931
|
return current;
|
|
1884
1932
|
}
|
|
1885
1933
|
async function catchUpSubgraph(subgraph, subgraphName) {
|
|
@@ -1910,10 +1958,11 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
1910
1958
|
});
|
|
1911
1959
|
const stats = new StatsAccumulator(subgraphName, true);
|
|
1912
1960
|
let processed = 0;
|
|
1913
|
-
|
|
1961
|
+
const batchConfig = resolveCatchupBatchConfig();
|
|
1962
|
+
let batchSize = batchConfig.defaultBatchSize;
|
|
1914
1963
|
let currentHeight = startBlock;
|
|
1915
|
-
let
|
|
1916
|
-
let nextBatchPromise = loadBlockRange(sourceDb, currentHeight,
|
|
1964
|
+
let prefetchedBatchEnd = Math.min(currentHeight + batchSize - 1, chainTip);
|
|
1965
|
+
let nextBatchPromise = batchConfig.prefetch ? loadBlockRange(sourceDb, currentHeight, prefetchedBatchEnd) : undefined;
|
|
1917
1966
|
while (currentHeight <= chainTip) {
|
|
1918
1967
|
const currentRow = await getSubgraph(targetDb, subgraphName);
|
|
1919
1968
|
if (!currentRow || currentRow.status !== "active") {
|
|
@@ -1923,12 +1972,21 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
1923
1972
|
});
|
|
1924
1973
|
break;
|
|
1925
1974
|
}
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1975
|
+
let batchEnd;
|
|
1976
|
+
let batch;
|
|
1977
|
+
if (nextBatchPromise) {
|
|
1978
|
+
batch = await nextBatchPromise;
|
|
1979
|
+
batchEnd = prefetchedBatchEnd;
|
|
1980
|
+
const nextStart = batchEnd + 1;
|
|
1981
|
+
if (nextStart <= chainTip) {
|
|
1982
|
+
prefetchedBatchEnd = Math.min(nextStart + batchSize - 1, chainTip);
|
|
1983
|
+
nextBatchPromise = loadBlockRange(sourceDb, nextStart, prefetchedBatchEnd);
|
|
1984
|
+
} else {
|
|
1985
|
+
nextBatchPromise = undefined;
|
|
1986
|
+
}
|
|
1987
|
+
} else {
|
|
1988
|
+
batchEnd = Math.min(currentHeight + batchSize - 1, chainTip);
|
|
1989
|
+
batch = await loadBlockRange(sourceDb, currentHeight, batchEnd);
|
|
1932
1990
|
}
|
|
1933
1991
|
const batchFailedBlocks = [];
|
|
1934
1992
|
for (let height = currentHeight;height <= batchEnd; height++) {
|
|
@@ -1982,7 +2040,7 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
1982
2040
|
});
|
|
1983
2041
|
}
|
|
1984
2042
|
const avg = avgEventsPerBlock(batch);
|
|
1985
|
-
batchSize = adjustBatchSize(batchSize, avg);
|
|
2043
|
+
batchSize = adjustBatchSize(batchSize, avg, batchConfig);
|
|
1986
2044
|
currentHeight = batchEnd + 1;
|
|
1987
2045
|
}
|
|
1988
2046
|
await stats.flush(targetDb);
|
|
@@ -2070,9 +2128,7 @@ import { listen as listen2 } from "@secondlayer/shared/queue/listener";
|
|
|
2070
2128
|
import {
|
|
2071
2129
|
getTargetDb as getTargetDb5
|
|
2072
2130
|
} from "@secondlayer/shared/db";
|
|
2073
|
-
import {
|
|
2074
|
-
getSubscriptionSigningSecret
|
|
2075
|
-
} from "@secondlayer/shared/db/queries/subscriptions";
|
|
2131
|
+
import { getSubscriptionSigningSecret } from "@secondlayer/shared/db/queries/subscriptions";
|
|
2076
2132
|
import { logger as logger9 } from "@secondlayer/shared/logger";
|
|
2077
2133
|
import { listen } from "@secondlayer/shared/queue/listener";
|
|
2078
2134
|
import { sql as sql4 } from "kysely";
|
|
@@ -2736,7 +2792,7 @@ async function startSubgraphOperationRunner(opts) {
|
|
|
2736
2792
|
}, HEARTBEAT_INTERVAL_MS);
|
|
2737
2793
|
const cancelPoll = setInterval(() => {
|
|
2738
2794
|
getSubgraphOperation(db, operation.id).then((row) => {
|
|
2739
|
-
if (row
|
|
2795
|
+
if ((!row || row.cancel_requested) && !controller.signal.aborted) {
|
|
2740
2796
|
controller.abort("user-cancelled");
|
|
2741
2797
|
}
|
|
2742
2798
|
}).catch((err) => {
|
|
@@ -2946,5 +3002,5 @@ var shutdown = async () => {
|
|
|
2946
3002
|
process.on("SIGINT", shutdown);
|
|
2947
3003
|
process.on("SIGTERM", shutdown);
|
|
2948
3004
|
|
|
2949
|
-
//# debugId=
|
|
3005
|
+
//# debugId=A1AAE72D48D7A5B964756E2164756E21
|
|
2950
3006
|
//# sourceMappingURL=service.js.map
|