envio 3.3.0-alpha.1 → 3.3.0-alpha.10
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/evm.schema.json +10 -0
- package/index.d.ts +45 -25
- package/package.json +7 -7
- package/src/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/Batch.res +0 -6
- package/src/Batch.res.mjs +1 -12
- package/src/BatchProcessing.res +7 -12
- package/src/BatchProcessing.res.mjs +8 -7
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +43 -9
- package/src/ChainFetching.res.mjs +34 -15
- package/src/ChainMetadata.res +1 -11
- package/src/ChainMetadata.res.mjs +1 -10
- package/src/ChainState.res +605 -151
- package/src/ChainState.res.mjs +427 -104
- package/src/ChainState.resi +72 -4
- package/src/Config.res +61 -33
- package/src/Config.res.mjs +50 -10
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/Core.res +14 -3
- package/src/CrossChainState.res +113 -89
- package/src/CrossChainState.res.mjs +64 -60
- package/src/CrossChainState.resi +1 -1
- package/src/Ecosystem.res +5 -6
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Envio.res +17 -11
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +177 -88
- package/src/EventConfigBuilder.res.mjs +99 -42
- package/src/EventProcessing.res +74 -28
- package/src/EventProcessing.res.mjs +55 -29
- package/src/ExitOnCaughtUp.res +10 -2
- package/src/ExitOnCaughtUp.res.mjs +10 -1
- package/src/FetchState.res +544 -356
- package/src/FetchState.res.mjs +412 -471
- package/src/HandlerLoader.res +8 -104
- package/src/HandlerLoader.res.mjs +2 -81
- package/src/HandlerRegister.res +518 -144
- package/src/HandlerRegister.res.mjs +285 -133
- package/src/HandlerRegister.resi +24 -8
- package/src/IndexerState.res +10 -3
- package/src/IndexerState.res.mjs +11 -4
- package/src/IndexerState.resi +2 -1
- package/src/IndexingAddresses.res +108 -0
- package/src/IndexingAddresses.res.mjs +101 -0
- package/src/IndexingAddresses.resi +34 -0
- package/src/Internal.res +155 -46
- package/src/Internal.res.mjs +30 -2
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +6 -6
- package/src/LogSelection.res +102 -165
- package/src/LogSelection.res.mjs +101 -116
- package/src/Main.res +71 -236
- package/src/Main.res.mjs +60 -145
- package/src/Metrics.res +74 -0
- package/src/Metrics.res.mjs +75 -0
- package/src/PgStorage.res +4 -4
- package/src/PgStorage.res.mjs +5 -5
- package/src/Prometheus.res +10 -63
- package/src/Prometheus.res.mjs +124 -171
- package/src/PruneStaleHistory.res +2 -2
- package/src/PruneStaleHistory.res.mjs +3 -3
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/Rollback.res +3 -3
- package/src/Rollback.res.mjs +4 -4
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateDeadInputTracker.res +85 -0
- package/src/SimulateDeadInputTracker.res.mjs +73 -0
- package/src/SimulateDeadInputTracker.resi +12 -0
- package/src/SimulateItems.res +91 -23
- package/src/SimulateItems.res.mjs +55 -32
- package/src/TestIndexer.res +54 -40
- package/src/TestIndexer.res.mjs +37 -30
- package/src/bindings/Performance.res +7 -0
- package/src/bindings/Performance.res.mjs +21 -0
- package/src/bindings/Performance.resi +7 -0
- package/src/bindings/Viem.res +0 -41
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +36 -33
- package/src/sources/EventRouter.res.mjs +13 -14
- package/src/sources/Evm.res +83 -72
- package/src/sources/Evm.res.mjs +53 -69
- package/src/sources/EvmChain.res +18 -20
- package/src/sources/EvmChain.res.mjs +15 -15
- package/src/sources/EvmRpcClient.res +74 -5
- package/src/sources/EvmRpcClient.res.mjs +13 -4
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +9 -6
- package/src/sources/Fuel.res.mjs +5 -10
- package/src/sources/HyperFuelSource.res +46 -50
- package/src/sources/HyperFuelSource.res.mjs +64 -54
- package/src/sources/HyperSync.res +39 -7
- package/src/sources/HyperSync.res.mjs +57 -37
- package/src/sources/HyperSync.resi +12 -2
- package/src/sources/HyperSyncClient.res +22 -111
- package/src/sources/HyperSyncClient.res.mjs +2 -30
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +94 -107
- package/src/sources/HyperSyncSource.res.mjs +82 -86
- package/src/sources/Rpc.res +15 -47
- package/src/sources/Rpc.res.mjs +25 -56
- package/src/sources/RpcSource.res +320 -467
- package/src/sources/RpcSource.res.mjs +268 -385
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +10 -4
- package/src/sources/SimulateSource.res.mjs +16 -6
- package/src/sources/Source.res +34 -6
- package/src/sources/SourceManager.res +77 -19
- package/src/sources/SourceManager.res.mjs +63 -21
- package/src/sources/SourceManager.resi +10 -0
- package/src/sources/Svm.res +31 -16
- package/src/sources/Svm.res.mjs +36 -13
- package/src/sources/SvmHyperSyncClient.res +5 -32
- package/src/sources/SvmHyperSyncSource.res +159 -134
- package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
- package/src/sources/TransactionStore.res +49 -0
- package/src/sources/TransactionStore.res.mjs +30 -0
- package/src/tui/Tui.res +13 -16
- package/src/tui/Tui.res.mjs +12 -14
- package/svm.schema.json +49 -37
- package/src/bindings/Hrtime.res +0 -58
- package/src/bindings/Hrtime.res.mjs +0 -90
- package/src/bindings/Hrtime.resi +0 -30
package/src/EventProcessing.res
CHANGED
|
@@ -39,7 +39,7 @@ let runEventHandlerOrThrow = async (
|
|
|
39
39
|
let eventItem = item->Internal.castUnsafeEventItem
|
|
40
40
|
|
|
41
41
|
//Include the load in time before handler
|
|
42
|
-
let timeBeforeHandler =
|
|
42
|
+
let timeBeforeHandler = Performance.now()
|
|
43
43
|
|
|
44
44
|
try {
|
|
45
45
|
let contextParams: UserContext.contextParams = {
|
|
@@ -72,10 +72,10 @@ let runEventHandlerOrThrow = async (
|
|
|
72
72
|
}),
|
|
73
73
|
)
|
|
74
74
|
}
|
|
75
|
-
let handlerDuration = timeBeforeHandler->
|
|
75
|
+
let handlerDuration = timeBeforeHandler->Performance.secondsSince
|
|
76
76
|
Prometheus.ProcessingHandler.increment(
|
|
77
|
-
~contract=eventItem.eventConfig.contractName,
|
|
78
|
-
~event=eventItem.eventConfig.name,
|
|
77
|
+
~contract=eventItem.onEventRegistration.eventConfig.contractName,
|
|
78
|
+
~event=eventItem.onEventRegistration.eventConfig.name,
|
|
79
79
|
~duration=handlerDuration,
|
|
80
80
|
)
|
|
81
81
|
}
|
|
@@ -90,7 +90,7 @@ let runHandlerOrThrow = async (
|
|
|
90
90
|
~chains: Internal.chains,
|
|
91
91
|
) => {
|
|
92
92
|
switch item {
|
|
93
|
-
| Block({
|
|
93
|
+
| Block({onBlockRegistration: {handler}, blockNumber}) =>
|
|
94
94
|
try {
|
|
95
95
|
let contextParams: UserContext.contextParams = {
|
|
96
96
|
item,
|
|
@@ -121,8 +121,8 @@ let runHandlerOrThrow = async (
|
|
|
121
121
|
}),
|
|
122
122
|
)
|
|
123
123
|
}
|
|
124
|
-
| Event({
|
|
125
|
-
switch
|
|
124
|
+
| Event({onEventRegistration}) =>
|
|
125
|
+
switch onEventRegistration.handler {
|
|
126
126
|
| Some(handler) =>
|
|
127
127
|
await item->runEventHandlerOrThrow(
|
|
128
128
|
~handler,
|
|
@@ -161,7 +161,7 @@ let preloadBatchOrThrow = async (
|
|
|
161
161
|
for idx in 0 to checkpointEventsProcessed - 1 {
|
|
162
162
|
let item = batch.items->Array.getUnsafe(itemIdx.contents + idx)
|
|
163
163
|
switch item {
|
|
164
|
-
| Event({
|
|
164
|
+
| Event({onEventRegistration: {handler, eventConfig: {contractName, name: eventName}}}) =>
|
|
165
165
|
switch handler {
|
|
166
166
|
| None => ()
|
|
167
167
|
| Some(handler) =>
|
|
@@ -200,7 +200,7 @@ let preloadBatchOrThrow = async (
|
|
|
200
200
|
| _ => ()
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
-
| Block({
|
|
203
|
+
| Block({onBlockRegistration: {handler}, blockNumber}) =>
|
|
204
204
|
try {
|
|
205
205
|
promises->Array.push(
|
|
206
206
|
handler({
|
|
@@ -264,11 +264,19 @@ let runBatchHandlersOrThrow = async (
|
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
let registerProcessEventBatchMetrics = (
|
|
268
|
-
logger
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
let registerProcessEventBatchMetrics = (
|
|
268
|
+
~logger,
|
|
269
|
+
~batch: Batch.t,
|
|
270
|
+
~loadDuration,
|
|
271
|
+
~handlerDuration,
|
|
272
|
+
) => {
|
|
273
|
+
batch.progressedChainsById->Dict.forEachWithKey((chainAfterBatch, chainId) => {
|
|
274
|
+
logger->Logging.childTrace({
|
|
275
|
+
"msg": "Finished processing",
|
|
276
|
+
"chainId": chainId->Int.fromString->Option.getUnsafe,
|
|
277
|
+
"batchSize": chainAfterBatch.batchSize,
|
|
278
|
+
"progress": chainAfterBatch.progressBlockNumber,
|
|
279
|
+
})
|
|
272
280
|
})
|
|
273
281
|
|
|
274
282
|
Prometheus.ProcessingBatch.registerMetrics(~loadDuration, ~handlerDuration)
|
|
@@ -281,6 +289,39 @@ type logPartitionInfo = {
|
|
|
281
289
|
lastItemBlockNumber?: int,
|
|
282
290
|
}
|
|
283
291
|
|
|
292
|
+
// Off the hot path: bulk-materialise the selected transaction and block fields
|
|
293
|
+
// for the batch's store-backed (HyperSync) items and write them onto the
|
|
294
|
+
// payloads, so handlers read plain objects. A batch can span chains, each with
|
|
295
|
+
// its own stores and field masks, so group items by chain before materialising.
|
|
296
|
+
let materializeBatchEvents = async (
|
|
297
|
+
batch: Batch.t,
|
|
298
|
+
~chainStates: dict<ChainState.t>,
|
|
299
|
+
~ecosystem,
|
|
300
|
+
) => {
|
|
301
|
+
switch chainStates->Dict.valuesToArray {
|
|
302
|
+
// Single-chain indexers (the common case): every item belongs to the one
|
|
303
|
+
// chain, so skip the per-chain grouping and its allocations.
|
|
304
|
+
| [cs] => await cs->ChainState.materializeBatchItems(~items=batch.items, ~ecosystem)
|
|
305
|
+
| _ =>
|
|
306
|
+
let itemsByChain: dict<array<Internal.item>> = Dict.make()
|
|
307
|
+
batch.items->Array.forEach(item => {
|
|
308
|
+
let chainId = item->Internal.getItemChainId->Int.toString
|
|
309
|
+
switch itemsByChain->Utils.Dict.dangerouslyGetNonOption(chainId) {
|
|
310
|
+
| Some(items) => items->Array.push(item)
|
|
311
|
+
| None => itemsByChain->Dict.set(chainId, [item])
|
|
312
|
+
}
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
let _ = await itemsByChain
|
|
316
|
+
->Dict.toArray
|
|
317
|
+
->Array.map(async ((chainId, items)) => {
|
|
318
|
+
let cs = chainStates->Dict.getUnsafe(chainId)
|
|
319
|
+
await cs->ChainState.materializeBatchItems(~items, ~ecosystem)
|
|
320
|
+
})
|
|
321
|
+
->Promise.all
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
284
325
|
let processEventBatch = async (
|
|
285
326
|
~batch: Batch.t,
|
|
286
327
|
~indexerState: IndexerState.t,
|
|
@@ -289,33 +330,33 @@ let processEventBatch = async (
|
|
|
289
330
|
~config: Config.t,
|
|
290
331
|
~chainStates: dict<ChainState.t>,
|
|
291
332
|
) => {
|
|
292
|
-
let totalBatchSize = batch.totalBatchSize
|
|
293
333
|
// Compute chains state for this batch
|
|
294
334
|
let chains: Internal.chains = chainStates->computeChainsState
|
|
295
335
|
|
|
296
336
|
let logger = Logging.getLogger()
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
}),
|
|
337
|
+
|
|
338
|
+
batch.progressedChainsById->Dict.forEachWithKey((chainAfterBatch, chainId) => {
|
|
339
|
+
logger->Logging.childTrace({
|
|
340
|
+
"msg": "Started processing",
|
|
341
|
+
"chainId": chainId->Int.fromString->Option.getUnsafe,
|
|
342
|
+
"batchSize": chainAfterBatch.batchSize,
|
|
343
|
+
})
|
|
306
344
|
})
|
|
307
345
|
|
|
308
346
|
try {
|
|
309
347
|
// Backpressure: keep processing within keepLatestChangesLimit of the cycle.
|
|
310
348
|
await indexerState->Writing.awaitCapacity
|
|
311
349
|
|
|
312
|
-
let timeRef =
|
|
350
|
+
let timeRef = Performance.now()
|
|
313
351
|
|
|
314
352
|
if batch.items->Utils.Array.notEmpty {
|
|
353
|
+
// Materialise store-backed transactions onto payloads before any handler
|
|
354
|
+
// (preload or execute) reads them.
|
|
355
|
+
await materializeBatchEvents(batch, ~chainStates, ~ecosystem=config.ecosystem.name)
|
|
315
356
|
await batch->preloadBatchOrThrow(~loadManager, ~persistence, ~indexerState, ~chains, ~config)
|
|
316
357
|
}
|
|
317
358
|
|
|
318
|
-
let elapsedTimeAfterLoaders = timeRef->
|
|
359
|
+
let elapsedTimeAfterLoaders = timeRef->Performance.secondsSince
|
|
319
360
|
|
|
320
361
|
if batch.items->Utils.Array.notEmpty {
|
|
321
362
|
await batch->runBatchHandlersOrThrow(
|
|
@@ -327,13 +368,18 @@ let processEventBatch = async (
|
|
|
327
368
|
)
|
|
328
369
|
}
|
|
329
370
|
|
|
330
|
-
let elapsedTimeAfterProcessing = timeRef->
|
|
371
|
+
let elapsedTimeAfterProcessing = timeRef->Performance.secondsSince
|
|
331
372
|
|
|
332
373
|
indexerState->Writing.commitBatch(~batch)
|
|
333
374
|
|
|
334
375
|
let loaderDuration = elapsedTimeAfterLoaders
|
|
335
376
|
let handlerDuration = elapsedTimeAfterProcessing -. loaderDuration
|
|
336
|
-
registerProcessEventBatchMetrics(
|
|
377
|
+
registerProcessEventBatchMetrics(
|
|
378
|
+
~logger,
|
|
379
|
+
~batch,
|
|
380
|
+
~loadDuration=loaderDuration,
|
|
381
|
+
~handlerDuration,
|
|
382
|
+
)
|
|
337
383
|
Ok()
|
|
338
384
|
} catch {
|
|
339
385
|
| Persistence.StorageError({message, reason}) =>
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Utils from "./Utils.res.mjs";
|
|
4
|
-
import * as Hrtime from "./bindings/Hrtime.res.mjs";
|
|
5
4
|
import * as Logging from "./Logging.res.mjs";
|
|
6
5
|
import * as Writing from "./Writing.res.mjs";
|
|
6
|
+
import * as Internal from "./Internal.res.mjs";
|
|
7
7
|
import * as Ecosystem from "./Ecosystem.res.mjs";
|
|
8
8
|
import * as ChainState from "./ChainState.res.mjs";
|
|
9
9
|
import * as Prometheus from "./Prometheus.res.mjs";
|
|
10
|
+
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
11
|
+
import * as Performance from "./bindings/Performance.res.mjs";
|
|
10
12
|
import * as Persistence from "./Persistence.res.mjs";
|
|
13
|
+
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
11
14
|
import * as UserContext from "./UserContext.res.mjs";
|
|
12
15
|
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
13
16
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
@@ -33,7 +36,7 @@ function computeChainsState(chainStates) {
|
|
|
33
36
|
let ProcessingError = /* @__PURE__ */Primitive_exceptions.create("EventProcessing.ProcessingError");
|
|
34
37
|
|
|
35
38
|
async function runEventHandlerOrThrow(item, checkpointId, handler, indexerState, loadManager, persistence, chains, config) {
|
|
36
|
-
let timeBeforeHandler =
|
|
39
|
+
let timeBeforeHandler = Performance.now();
|
|
37
40
|
try {
|
|
38
41
|
let contextParams = {
|
|
39
42
|
item: item,
|
|
@@ -61,13 +64,13 @@ async function runEventHandlerOrThrow(item, checkpointId, handler, indexerState,
|
|
|
61
64
|
Error: new Error()
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
|
-
let handlerDuration =
|
|
65
|
-
return Prometheus.ProcessingHandler.increment(item.eventConfig.contractName, item.eventConfig.name, handlerDuration);
|
|
67
|
+
let handlerDuration = Performance.secondsSince(timeBeforeHandler);
|
|
68
|
+
return Prometheus.ProcessingHandler.increment(item.onEventRegistration.eventConfig.contractName, item.onEventRegistration.eventConfig.name, handlerDuration);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
async function runHandlerOrThrow(item, checkpointId, indexerState, loadManager, persistence, config, chains) {
|
|
69
72
|
if (item.kind === 0) {
|
|
70
|
-
let handler = item.
|
|
73
|
+
let handler = item.onEventRegistration.handler;
|
|
71
74
|
if (handler !== undefined) {
|
|
72
75
|
return await runEventHandlerOrThrow(item, checkpointId, handler, indexerState, loadManager, persistence, chains, config);
|
|
73
76
|
} else {
|
|
@@ -86,7 +89,7 @@ async function runHandlerOrThrow(item, checkpointId, indexerState, loadManager,
|
|
|
86
89
|
config: config,
|
|
87
90
|
isResolved: false
|
|
88
91
|
};
|
|
89
|
-
await item.
|
|
92
|
+
await item.onBlockRegistration.handler(Ecosystem.makeOnBlockArgs(item.blockNumber, config.ecosystem, UserContext.getHandlerContext(contextParams)));
|
|
90
93
|
contextParams.isResolved = true;
|
|
91
94
|
return;
|
|
92
95
|
} catch (raw_exn) {
|
|
@@ -110,11 +113,12 @@ async function preloadBatchOrThrow(batch, loadManager, persistence, config, inde
|
|
|
110
113
|
for (let idx = 0; idx < checkpointEventsProcessed; ++idx) {
|
|
111
114
|
let item = batch.items[itemIdx + idx | 0];
|
|
112
115
|
if (item.kind === 0) {
|
|
113
|
-
let match = item.
|
|
116
|
+
let match = item.onEventRegistration;
|
|
114
117
|
let handler = match.handler;
|
|
115
118
|
if (handler !== undefined) {
|
|
116
|
-
let
|
|
117
|
-
let
|
|
119
|
+
let match$1 = match.eventConfig;
|
|
120
|
+
let contractName = match$1.contractName;
|
|
121
|
+
let eventName = match$1.name;
|
|
118
122
|
try {
|
|
119
123
|
let timerRef = Prometheus.PreloadHandler.startOperation(contractName, eventName);
|
|
120
124
|
promises.push(Utils.$$Promise.silentCatch(handler({
|
|
@@ -137,7 +141,7 @@ async function preloadBatchOrThrow(batch, loadManager, persistence, config, inde
|
|
|
137
141
|
}
|
|
138
142
|
} else {
|
|
139
143
|
try {
|
|
140
|
-
promises.push(Utils.$$Promise.silentCatch(item.
|
|
144
|
+
promises.push(Utils.$$Promise.silentCatch(item.onBlockRegistration.handler(Ecosystem.makeOnBlockArgs(item.blockNumber, config.ecosystem, UserContext.getHandlerContext({
|
|
141
145
|
item: item,
|
|
142
146
|
checkpointId: checkpointId,
|
|
143
147
|
indexerState: indexerState,
|
|
@@ -171,41 +175,62 @@ async function runBatchHandlersOrThrow(batch, indexerState, loadManager, persist
|
|
|
171
175
|
}
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
function registerProcessEventBatchMetrics(logger, loadDuration, handlerDuration) {
|
|
175
|
-
Logging.childTrace(logger, {
|
|
176
|
-
msg: "Finished processing
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
function registerProcessEventBatchMetrics(logger, batch, loadDuration, handlerDuration) {
|
|
179
|
+
Stdlib_Dict.forEachWithKey(batch.progressedChainsById, (chainAfterBatch, chainId) => Logging.childTrace(logger, {
|
|
180
|
+
msg: "Finished processing",
|
|
181
|
+
chainId: Stdlib_Int.fromString(chainId, undefined),
|
|
182
|
+
batchSize: chainAfterBatch.batchSize,
|
|
183
|
+
progress: chainAfterBatch.progressBlockNumber
|
|
184
|
+
}));
|
|
180
185
|
Prometheus.ProcessingBatch.registerMetrics(loadDuration, handlerDuration);
|
|
181
186
|
}
|
|
182
187
|
|
|
188
|
+
async function materializeBatchEvents(batch, chainStates, ecosystem) {
|
|
189
|
+
let match = Object.values(chainStates);
|
|
190
|
+
if (match.length !== 1) {
|
|
191
|
+
let itemsByChain = {};
|
|
192
|
+
batch.items.forEach(item => {
|
|
193
|
+
let chainId = Internal.getItemChainId(item).toString();
|
|
194
|
+
let items = itemsByChain[chainId];
|
|
195
|
+
if (items !== undefined) {
|
|
196
|
+
items.push(item);
|
|
197
|
+
} else {
|
|
198
|
+
itemsByChain[chainId] = [item];
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
await Promise.all(Object.entries(itemsByChain).map(async param => {
|
|
202
|
+
let cs = chainStates[param[0]];
|
|
203
|
+
return await ChainState.materializeBatchItems(cs, param[1], ecosystem);
|
|
204
|
+
}));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
let cs = match[0];
|
|
208
|
+
return await ChainState.materializeBatchItems(cs, batch.items, ecosystem);
|
|
209
|
+
}
|
|
210
|
+
|
|
183
211
|
async function processEventBatch(batch, indexerState, loadManager, persistence, config, chainStates) {
|
|
184
|
-
let totalBatchSize = batch.totalBatchSize;
|
|
185
212
|
let chains = computeChainsState(chainStates);
|
|
186
213
|
let logger = Logging.getLogger();
|
|
187
|
-
Logging.childTrace(logger, {
|
|
188
|
-
msg: "Started processing
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
progress: chainAfterBatch.progressBlockNumber
|
|
193
|
-
}))
|
|
194
|
-
});
|
|
214
|
+
Stdlib_Dict.forEachWithKey(batch.progressedChainsById, (chainAfterBatch, chainId) => Logging.childTrace(logger, {
|
|
215
|
+
msg: "Started processing",
|
|
216
|
+
chainId: Stdlib_Int.fromString(chainId, undefined),
|
|
217
|
+
batchSize: chainAfterBatch.batchSize
|
|
218
|
+
}));
|
|
195
219
|
try {
|
|
196
220
|
await Writing.awaitCapacity(indexerState);
|
|
197
|
-
let timeRef =
|
|
221
|
+
let timeRef = Performance.now();
|
|
198
222
|
if (Utils.$$Array.notEmpty(batch.items)) {
|
|
223
|
+
await materializeBatchEvents(batch, chainStates, config.ecosystem.name);
|
|
199
224
|
await preloadBatchOrThrow(batch, loadManager, persistence, config, indexerState, chains);
|
|
200
225
|
}
|
|
201
|
-
let elapsedTimeAfterLoaders =
|
|
226
|
+
let elapsedTimeAfterLoaders = Performance.secondsSince(timeRef);
|
|
202
227
|
if (Utils.$$Array.notEmpty(batch.items)) {
|
|
203
228
|
await runBatchHandlersOrThrow(batch, indexerState, loadManager, persistence, config, chains);
|
|
204
229
|
}
|
|
205
|
-
let elapsedTimeAfterProcessing =
|
|
230
|
+
let elapsedTimeAfterProcessing = Performance.secondsSince(timeRef);
|
|
206
231
|
Writing.commitBatch(indexerState, batch);
|
|
207
232
|
let handlerDuration = elapsedTimeAfterProcessing - elapsedTimeAfterLoaders;
|
|
208
|
-
registerProcessEventBatchMetrics(logger, elapsedTimeAfterLoaders, handlerDuration);
|
|
233
|
+
registerProcessEventBatchMetrics(logger, batch, elapsedTimeAfterLoaders, handlerDuration);
|
|
209
234
|
return {
|
|
210
235
|
TAG: "Ok",
|
|
211
236
|
_0: undefined
|
|
@@ -240,6 +265,7 @@ export {
|
|
|
240
265
|
preloadBatchOrThrow,
|
|
241
266
|
runBatchHandlersOrThrow,
|
|
242
267
|
registerProcessEventBatchMetrics,
|
|
268
|
+
materializeBatchEvents,
|
|
243
269
|
processEventBatch,
|
|
244
270
|
}
|
|
245
271
|
/* Utils Not a pure module */
|
package/src/ExitOnCaughtUp.res
CHANGED
|
@@ -4,7 +4,15 @@ let run = async (state: IndexerState.t) => {
|
|
|
4
4
|
ChainMetadata.stage(state)
|
|
5
5
|
await state->Writing.flush
|
|
6
6
|
if !(state->IndexerState.isStopped) && !(state->IndexerState.isResolvingReorg) {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// A simulate run fails here when a provided item never reached a handler —
|
|
8
|
+
// dead test code. The tracker is None (a no-op) off the simulate path.
|
|
9
|
+
switch state
|
|
10
|
+
->IndexerState.simulateDeadInputTracker
|
|
11
|
+
->Option.flatMap(SimulateDeadInputTracker.failureMessage) {
|
|
12
|
+
| None =>
|
|
13
|
+
Logging.info("Exiting with success")
|
|
14
|
+
NodeJs.process->NodeJs.exitWithCode(Success)
|
|
15
|
+
| Some(message) => state->IndexerState.errorExit(ErrorHandling.make(Utils.Error.make(message)))
|
|
16
|
+
}
|
|
9
17
|
}
|
|
10
18
|
}
|
|
@@ -5,11 +5,20 @@ import * as Writing from "./Writing.res.mjs";
|
|
|
5
5
|
import * as Process from "process";
|
|
6
6
|
import * as IndexerState from "./IndexerState.res.mjs";
|
|
7
7
|
import * as ChainMetadata from "./ChainMetadata.res.mjs";
|
|
8
|
+
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
9
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
10
|
+
import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
|
|
8
11
|
|
|
9
12
|
async function run(state) {
|
|
10
13
|
ChainMetadata.stage(state);
|
|
11
14
|
await Writing.flush(state);
|
|
12
|
-
if (
|
|
15
|
+
if (IndexerState.isStopped(state) || IndexerState.isResolvingReorg(state)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
let message = Stdlib_Option.flatMap(IndexerState.simulateDeadInputTracker(state), SimulateDeadInputTracker.failureMessage);
|
|
19
|
+
if (message !== undefined) {
|
|
20
|
+
return IndexerState.errorExit(state, ErrorHandling.make(new Error(message), undefined, undefined));
|
|
21
|
+
} else {
|
|
13
22
|
Logging.info("Exiting with success");
|
|
14
23
|
Process.exit(0);
|
|
15
24
|
return;
|