ponder 0.14.13 → 0.15.0
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/CHANGELOG.md +16 -0
- package/dist/esm/bin/commands/createViews.js +28 -11
- package/dist/esm/bin/commands/createViews.js.map +1 -1
- package/dist/esm/bin/commands/dev.js +42 -22
- package/dist/esm/bin/commands/dev.js.map +1 -1
- package/dist/esm/bin/commands/prune.js +3 -0
- package/dist/esm/bin/commands/prune.js.map +1 -1
- package/dist/esm/bin/commands/serve.js +4 -1
- package/dist/esm/bin/commands/serve.js.map +1 -1
- package/dist/esm/bin/commands/start.js +18 -6
- package/dist/esm/bin/commands/start.js.map +1 -1
- package/dist/esm/bin/isolatedController.js +200 -0
- package/dist/esm/bin/isolatedController.js.map +1 -0
- package/dist/esm/bin/isolatedWorker.js +146 -0
- package/dist/esm/bin/isolatedWorker.js.map +1 -0
- package/dist/esm/build/config.js +322 -402
- package/dist/esm/build/config.js.map +1 -1
- package/dist/esm/build/index.js +8 -11
- package/dist/esm/build/index.js.map +1 -1
- package/dist/esm/build/pre.js +1 -4
- package/dist/esm/build/pre.js.map +1 -1
- package/dist/esm/build/schema.js +25 -3
- package/dist/esm/build/schema.js.map +1 -1
- package/dist/esm/client/index.js +306 -42
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/database/actions.js +264 -104
- package/dist/esm/database/actions.js.map +1 -1
- package/dist/esm/database/index.js +39 -33
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/database/queryBuilder.js +1 -0
- package/dist/esm/database/queryBuilder.js.map +1 -1
- package/dist/esm/drizzle/index.js +11 -7
- package/dist/esm/drizzle/index.js.map +1 -1
- package/dist/esm/drizzle/onchain.js +18 -0
- package/dist/esm/drizzle/onchain.js.map +1 -1
- package/dist/esm/indexing/client.js +32 -25
- package/dist/esm/indexing/client.js.map +1 -1
- package/dist/esm/indexing/index.js +110 -178
- package/dist/esm/indexing/index.js.map +1 -1
- package/dist/esm/indexing/profile.js +1 -1
- package/dist/esm/indexing/profile.js.map +1 -1
- package/dist/esm/indexing-store/cache.js +196 -274
- package/dist/esm/indexing-store/cache.js.map +1 -1
- package/dist/esm/indexing-store/historical.js +17 -13
- package/dist/esm/indexing-store/historical.js.map +1 -1
- package/dist/esm/indexing-store/index.js +10 -1
- package/dist/esm/indexing-store/index.js.map +1 -1
- package/dist/esm/indexing-store/profile.js +3 -3
- package/dist/esm/indexing-store/profile.js.map +1 -1
- package/dist/esm/indexing-store/realtime.js +27 -2
- package/dist/esm/indexing-store/realtime.js.map +1 -1
- package/dist/esm/internal/errors.js +28 -0
- package/dist/esm/internal/errors.js.map +1 -1
- package/dist/esm/internal/metrics.js +279 -82
- package/dist/esm/internal/metrics.js.map +1 -1
- package/dist/esm/internal/options.js +1 -0
- package/dist/esm/internal/options.js.map +1 -1
- package/dist/esm/internal/telemetry.js +1 -1
- package/dist/esm/internal/telemetry.js.map +1 -1
- package/dist/esm/rpc/http.js +130 -0
- package/dist/esm/rpc/http.js.map +1 -0
- package/dist/esm/rpc/index.js +38 -7
- package/dist/esm/rpc/index.js.map +1 -1
- package/dist/esm/runtime/events.js +179 -212
- package/dist/esm/runtime/events.js.map +1 -1
- package/dist/esm/runtime/filter.js +71 -0
- package/dist/esm/runtime/filter.js.map +1 -1
- package/dist/esm/runtime/fragments.js +78 -73
- package/dist/esm/runtime/fragments.js.map +1 -1
- package/dist/esm/runtime/historical.js +306 -130
- package/dist/esm/runtime/historical.js.map +1 -1
- package/dist/esm/runtime/index.js +183 -58
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/isolated.js +462 -0
- package/dist/esm/runtime/isolated.js.map +1 -0
- package/dist/esm/runtime/multichain.js +80 -73
- package/dist/esm/runtime/multichain.js.map +1 -1
- package/dist/esm/runtime/omnichain.js +82 -75
- package/dist/esm/runtime/omnichain.js.map +1 -1
- package/dist/esm/runtime/realtime.js +198 -66
- package/dist/esm/runtime/realtime.js.map +1 -1
- package/dist/esm/sync-historical/index.js +416 -457
- package/dist/esm/sync-historical/index.js.map +1 -1
- package/dist/esm/sync-realtime/bloom.js +3 -3
- package/dist/esm/sync-realtime/bloom.js.map +1 -1
- package/dist/esm/sync-realtime/index.js +27 -46
- package/dist/esm/sync-realtime/index.js.map +1 -1
- package/dist/esm/sync-store/index.js +112 -63
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/esm/utils/abi.js +20 -32
- package/dist/esm/utils/abi.js.map +1 -1
- package/dist/esm/utils/chunk.js +8 -0
- package/dist/esm/utils/chunk.js.map +1 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js +19 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js.map +1 -0
- package/dist/esm/{client/parse.js → utils/sql-parse.js} +94 -80
- package/dist/esm/utils/sql-parse.js.map +1 -0
- package/dist/types/bin/commands/createViews.d.ts.map +1 -1
- package/dist/types/bin/commands/dev.d.ts.map +1 -1
- package/dist/types/bin/commands/prune.d.ts.map +1 -1
- package/dist/types/bin/commands/serve.d.ts.map +1 -1
- package/dist/types/bin/commands/start.d.ts.map +1 -1
- package/dist/types/bin/isolatedController.d.ts +13 -0
- package/dist/types/bin/isolatedController.d.ts.map +1 -0
- package/dist/types/bin/isolatedWorker.d.ts +9 -0
- package/dist/types/bin/isolatedWorker.d.ts.map +1 -0
- package/dist/types/build/config.d.ts +29 -11
- package/dist/types/build/config.d.ts.map +1 -1
- package/dist/types/build/index.d.ts +3 -2
- package/dist/types/build/index.d.ts.map +1 -1
- package/dist/types/build/pre.d.ts +1 -1
- package/dist/types/build/pre.d.ts.map +1 -1
- package/dist/types/build/schema.d.ts +5 -3
- package/dist/types/build/schema.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +3 -3
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/database/actions.d.ts +53 -7
- package/dist/types/database/actions.d.ts.map +1 -1
- package/dist/types/database/index.d.ts +21 -21
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/database/queryBuilder.d.ts.map +1 -1
- package/dist/types/drizzle/index.d.ts +4 -5
- package/dist/types/drizzle/index.d.ts.map +1 -1
- package/dist/types/drizzle/onchain.d.ts +6 -0
- package/dist/types/drizzle/onchain.d.ts.map +1 -1
- package/dist/types/indexing/client.d.ts.map +1 -1
- package/dist/types/indexing/index.d.ts +2 -5
- package/dist/types/indexing/index.d.ts.map +1 -1
- package/dist/types/indexing-store/cache.d.ts +3 -2
- package/dist/types/indexing-store/cache.d.ts.map +1 -1
- package/dist/types/indexing-store/historical.d.ts +2 -1
- package/dist/types/indexing-store/historical.d.ts.map +1 -1
- package/dist/types/indexing-store/index.d.ts +1 -0
- package/dist/types/indexing-store/index.d.ts.map +1 -1
- package/dist/types/indexing-store/realtime.d.ts +2 -1
- package/dist/types/indexing-store/realtime.d.ts.map +1 -1
- package/dist/types/internal/errors.d.ts +5 -0
- package/dist/types/internal/errors.d.ts.map +1 -1
- package/dist/types/internal/metrics.d.ts +21 -0
- package/dist/types/internal/metrics.d.ts.map +1 -1
- package/dist/types/internal/options.d.ts +2 -0
- package/dist/types/internal/options.d.ts.map +1 -1
- package/dist/types/internal/types.d.ts +66 -58
- package/dist/types/internal/types.d.ts.map +1 -1
- package/dist/types/rpc/http.d.ts +17 -0
- package/dist/types/rpc/http.d.ts.map +1 -0
- package/dist/types/rpc/index.d.ts.map +1 -1
- package/dist/types/runtime/events.d.ts +4 -4
- package/dist/types/runtime/events.d.ts.map +1 -1
- package/dist/types/runtime/filter.d.ts +5 -1
- package/dist/types/runtime/filter.d.ts.map +1 -1
- package/dist/types/runtime/fragments.d.ts +4 -3
- package/dist/types/runtime/fragments.d.ts.map +1 -1
- package/dist/types/runtime/historical.d.ts +29 -13
- package/dist/types/runtime/historical.d.ts.map +1 -1
- package/dist/types/runtime/index.d.ts +49 -6
- package/dist/types/runtime/index.d.ts.map +1 -1
- package/dist/types/runtime/init.d.ts +5 -5
- package/dist/types/runtime/init.d.ts.map +1 -1
- package/dist/types/runtime/isolated.d.ts +14 -0
- package/dist/types/runtime/isolated.d.ts.map +1 -0
- package/dist/types/runtime/multichain.d.ts.map +1 -1
- package/dist/types/runtime/omnichain.d.ts.map +1 -1
- package/dist/types/runtime/realtime.d.ts +21 -10
- package/dist/types/runtime/realtime.d.ts.map +1 -1
- package/dist/types/sync-historical/index.d.ts +18 -8
- package/dist/types/sync-historical/index.d.ts.map +1 -1
- package/dist/types/sync-realtime/bloom.d.ts.map +1 -1
- package/dist/types/sync-realtime/index.d.ts +2 -2
- package/dist/types/sync-realtime/index.d.ts.map +1 -1
- package/dist/types/sync-store/index.d.ts +9 -9
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/dist/types/utils/abi.d.ts +3 -34
- package/dist/types/utils/abi.d.ts.map +1 -1
- package/dist/types/utils/chunk.d.ts +2 -0
- package/dist/types/utils/chunk.d.ts.map +1 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts +8 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts.map +1 -0
- package/dist/types/utils/sql-parse.d.ts +21 -0
- package/dist/types/utils/sql-parse.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/bin/commands/createViews.ts +35 -15
- package/src/bin/commands/dev.ts +43 -21
- package/src/bin/commands/prune.ts +6 -0
- package/src/bin/commands/serve.ts +4 -1
- package/src/bin/commands/start.ts +20 -5
- package/src/bin/isolatedController.ts +300 -0
- package/src/bin/isolatedWorker.ts +192 -0
- package/src/build/config.ts +570 -632
- package/src/build/index.ts +14 -14
- package/src/build/pre.ts +1 -4
- package/src/build/schema.ts +49 -4
- package/src/client/index.ts +386 -48
- package/src/config/index.ts +3 -3
- package/src/database/actions.ts +469 -120
- package/src/database/index.ts +85 -58
- package/src/database/queryBuilder.ts +1 -0
- package/src/drizzle/index.ts +15 -7
- package/src/drizzle/onchain.ts +19 -0
- package/src/indexing/client.ts +38 -25
- package/src/indexing/index.ts +137 -230
- package/src/indexing/profile.ts +1 -1
- package/src/indexing-store/cache.ts +285 -414
- package/src/indexing-store/historical.ts +20 -10
- package/src/indexing-store/index.ts +16 -0
- package/src/indexing-store/profile.ts +3 -3
- package/src/indexing-store/realtime.ts +28 -0
- package/src/internal/errors.ts +26 -0
- package/src/internal/metrics.ts +341 -111
- package/src/internal/options.ts +4 -0
- package/src/internal/telemetry.ts +1 -1
- package/src/internal/types.ts +70 -87
- package/src/rpc/http.ts +164 -0
- package/src/rpc/index.ts +39 -7
- package/src/runtime/events.ts +195 -240
- package/src/runtime/filter.ts +85 -1
- package/src/runtime/fragments.ts +109 -113
- package/src/runtime/historical.ts +467 -189
- package/src/runtime/index.ts +337 -69
- package/src/runtime/init.ts +5 -5
- package/src/runtime/isolated.ts +768 -0
- package/src/runtime/multichain.ts +137 -102
- package/src/runtime/omnichain.ts +138 -106
- package/src/runtime/realtime.ts +322 -123
- package/src/sync-historical/index.ts +556 -692
- package/src/sync-realtime/bloom.ts +7 -3
- package/src/sync-realtime/index.ts +31 -46
- package/src/sync-store/index.ts +189 -95
- package/src/utils/abi.ts +33 -90
- package/src/utils/chunk.ts +7 -0
- package/src/utils/promiseAllSettledWithThrow.ts +27 -0
- package/src/{client/parse.ts → utils/sql-parse.ts} +100 -90
- package/dist/esm/client/parse.js.map +0 -1
- package/dist/types/client/parse.d.ts +0 -14
- package/dist/types/client/parse.d.ts.map +0 -1
package/src/internal/metrics.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { type Worker, parentPort } from "node:worker_threads";
|
|
2
|
+
import {
|
|
3
|
+
type PromiseWithResolvers,
|
|
4
|
+
promiseWithResolvers,
|
|
5
|
+
} from "@/utils/promiseWithResolvers.js";
|
|
1
6
|
import { truncate } from "@/utils/truncate.js";
|
|
2
7
|
import { getTableName, isTable } from "drizzle-orm";
|
|
3
8
|
import prometheus from "prom-client";
|
|
4
|
-
import type { IndexingBuild, SchemaBuild } from "./types.js";
|
|
9
|
+
import type { IndexingBuild, PreBuild, SchemaBuild } from "./types.js";
|
|
5
10
|
|
|
6
11
|
const sometimesIODurationMs = [
|
|
7
12
|
0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100, 500, 1_000, 5_000,
|
|
@@ -17,6 +22,9 @@ const httpRequestSizeBytes = [
|
|
|
17
22
|
10_000_000,
|
|
18
23
|
];
|
|
19
24
|
|
|
25
|
+
const GET_METRICS_REQ = "prom-client:getMetricsReq";
|
|
26
|
+
const GET_METRICS_RES = "prom-client:getMetricsRes";
|
|
27
|
+
|
|
20
28
|
export class MetricsService {
|
|
21
29
|
registry: prometheus.Registry;
|
|
22
30
|
start_timestamp: number;
|
|
@@ -124,12 +132,14 @@ export class MetricsService {
|
|
|
124
132
|
help: "Ponder version information",
|
|
125
133
|
labelNames: ["version", "major", "minor", "patch"] as const,
|
|
126
134
|
registers: [this.registry],
|
|
135
|
+
aggregator: "first",
|
|
127
136
|
});
|
|
128
137
|
this.ponder_settings_info = new prometheus.Gauge({
|
|
129
138
|
name: "ponder_settings_info",
|
|
130
139
|
help: "Ponder settings information",
|
|
131
140
|
labelNames: ["ordering", "database", "command"] as const,
|
|
132
141
|
registers: [this.registry],
|
|
142
|
+
aggregator: "first",
|
|
133
143
|
});
|
|
134
144
|
|
|
135
145
|
this.ponder_historical_concurrency_group_duration = new prometheus.Gauge({
|
|
@@ -137,18 +147,21 @@ export class MetricsService {
|
|
|
137
147
|
help: "Duration of historical concurrency groups",
|
|
138
148
|
labelNames: ["group"] as const,
|
|
139
149
|
registers: [this.registry],
|
|
150
|
+
aggregator: "sum",
|
|
140
151
|
});
|
|
141
152
|
this.ponder_historical_extract_duration = new prometheus.Gauge({
|
|
142
153
|
name: "ponder_historical_extract_duration",
|
|
143
154
|
help: "Duration of historical extract phase",
|
|
144
155
|
labelNames: ["step"] as const,
|
|
145
156
|
registers: [this.registry],
|
|
157
|
+
aggregator: "sum",
|
|
146
158
|
});
|
|
147
159
|
this.ponder_historical_transform_duration = new prometheus.Gauge({
|
|
148
160
|
name: "ponder_historical_transform_duration",
|
|
149
161
|
help: "Duration of historical transform phase",
|
|
150
162
|
labelNames: ["step"] as const,
|
|
151
163
|
registers: [this.registry],
|
|
164
|
+
aggregator: "sum",
|
|
152
165
|
});
|
|
153
166
|
|
|
154
167
|
this.ponder_historical_start_timestamp_seconds = new prometheus.Gauge({
|
|
@@ -156,12 +169,14 @@ export class MetricsService {
|
|
|
156
169
|
help: "Timestamp at which historical indexing started",
|
|
157
170
|
labelNames: ["chain"] as const,
|
|
158
171
|
registers: [this.registry],
|
|
172
|
+
aggregator: "min",
|
|
159
173
|
});
|
|
160
174
|
this.ponder_historical_end_timestamp_seconds = new prometheus.Gauge({
|
|
161
175
|
name: "ponder_historical_end_timestamp_seconds",
|
|
162
176
|
help: "Timestamp at which historical indexing ended",
|
|
163
177
|
labelNames: ["chain"] as const,
|
|
164
178
|
registers: [this.registry],
|
|
179
|
+
aggregator: "max",
|
|
165
180
|
});
|
|
166
181
|
|
|
167
182
|
this.ponder_historical_total_indexing_seconds = new prometheus.Gauge({
|
|
@@ -169,30 +184,35 @@ export class MetricsService {
|
|
|
169
184
|
help: "Total number of seconds that are required",
|
|
170
185
|
labelNames: ["chain"] as const,
|
|
171
186
|
registers: [this.registry],
|
|
187
|
+
aggregator: "sum",
|
|
172
188
|
});
|
|
173
189
|
this.ponder_historical_cached_indexing_seconds = new prometheus.Gauge({
|
|
174
190
|
name: "ponder_historical_cached_indexing_seconds",
|
|
175
191
|
help: "Number of seconds that have been cached",
|
|
176
192
|
labelNames: ["chain"] as const,
|
|
177
193
|
registers: [this.registry],
|
|
194
|
+
aggregator: "sum",
|
|
178
195
|
});
|
|
179
196
|
this.ponder_historical_completed_indexing_seconds = new prometheus.Gauge({
|
|
180
197
|
name: "ponder_historical_completed_indexing_seconds",
|
|
181
198
|
help: "Number of seconds that have been completed",
|
|
182
199
|
labelNames: ["chain"] as const,
|
|
183
200
|
registers: [this.registry],
|
|
201
|
+
aggregator: "sum",
|
|
184
202
|
});
|
|
185
203
|
this.ponder_indexing_completed_events = new prometheus.Gauge({
|
|
186
204
|
name: "ponder_indexing_completed_events",
|
|
187
205
|
help: "Number of events that have been processed",
|
|
188
206
|
labelNames: ["chain", "event"] as const,
|
|
189
207
|
registers: [this.registry],
|
|
208
|
+
aggregator: "sum",
|
|
190
209
|
});
|
|
191
210
|
this.ponder_indexing_timestamp = new prometheus.Gauge({
|
|
192
211
|
name: "ponder_indexing_timestamp",
|
|
193
212
|
help: "Timestamp through which all events have been completed",
|
|
194
213
|
labelNames: ["chain"] as const,
|
|
195
214
|
registers: [this.registry],
|
|
215
|
+
aggregator: "first",
|
|
196
216
|
});
|
|
197
217
|
this.ponder_indexing_function_duration = new prometheus.Histogram({
|
|
198
218
|
name: "ponder_indexing_function_duration",
|
|
@@ -200,6 +220,7 @@ export class MetricsService {
|
|
|
200
220
|
labelNames: ["chain", "event"] as const,
|
|
201
221
|
buckets: sometimesIODurationMs,
|
|
202
222
|
registers: [this.registry],
|
|
223
|
+
aggregator: "sum",
|
|
203
224
|
});
|
|
204
225
|
this.ponder_indexing_cache_query_duration = new prometheus.Histogram({
|
|
205
226
|
name: "ponder_indexing_cache_query_duration",
|
|
@@ -207,6 +228,7 @@ export class MetricsService {
|
|
|
207
228
|
labelNames: ["table", "method"] as const,
|
|
208
229
|
buckets: alwaysIODurationMs,
|
|
209
230
|
registers: [this.registry],
|
|
231
|
+
aggregator: "sum",
|
|
210
232
|
});
|
|
211
233
|
this.ponder_indexing_rpc_action_duration = new prometheus.Histogram({
|
|
212
234
|
name: "ponder_indexing_rpc_action_duration",
|
|
@@ -214,36 +236,42 @@ export class MetricsService {
|
|
|
214
236
|
labelNames: ["action"] as const,
|
|
215
237
|
buckets: sometimesIODurationMs,
|
|
216
238
|
registers: [this.registry],
|
|
239
|
+
aggregator: "sum",
|
|
217
240
|
});
|
|
218
241
|
this.ponder_indexing_rpc_prefetch_total = new prometheus.Counter({
|
|
219
242
|
name: "ponder_indexing_rpc_prefetch_total",
|
|
220
243
|
help: "Number of RPC prefetches",
|
|
221
244
|
labelNames: ["chain", "method", "type"] as const,
|
|
222
245
|
registers: [this.registry],
|
|
246
|
+
aggregator: "sum",
|
|
223
247
|
});
|
|
224
248
|
this.ponder_indexing_rpc_requests_total = new prometheus.Counter({
|
|
225
249
|
name: "ponder_indexing_rpc_requests_total",
|
|
226
250
|
help: "Number of RPC requests",
|
|
227
251
|
labelNames: ["chain", "method", "type"] as const,
|
|
228
252
|
registers: [this.registry],
|
|
253
|
+
aggregator: "sum",
|
|
229
254
|
});
|
|
230
255
|
this.ponder_indexing_cache_requests_total = new prometheus.Counter({
|
|
231
256
|
name: "ponder_indexing_cache_requests_total",
|
|
232
257
|
help: "Number of cache accesses",
|
|
233
258
|
labelNames: ["table", "type"] as const,
|
|
234
259
|
registers: [this.registry],
|
|
260
|
+
aggregator: "sum",
|
|
235
261
|
});
|
|
236
262
|
this.ponder_indexing_store_queries_total = new prometheus.Counter({
|
|
237
263
|
name: "ponder_indexing_store_queries_total",
|
|
238
264
|
help: "Number of indexing store operations",
|
|
239
265
|
labelNames: ["table", "method"] as const,
|
|
240
266
|
registers: [this.registry],
|
|
267
|
+
aggregator: "sum",
|
|
241
268
|
});
|
|
242
269
|
this.ponder_indexing_store_raw_sql_duration = new prometheus.Histogram({
|
|
243
270
|
name: "ponder_indexing_store_raw_sql_duration",
|
|
244
271
|
help: "Duration of raw SQL store operations",
|
|
245
272
|
buckets: alwaysIODurationMs,
|
|
246
273
|
registers: [this.registry],
|
|
274
|
+
aggregator: "sum",
|
|
247
275
|
});
|
|
248
276
|
|
|
249
277
|
this.ponder_sync_block = new prometheus.Gauge({
|
|
@@ -251,24 +279,28 @@ export class MetricsService {
|
|
|
251
279
|
help: "Closest-to-tip synced block number",
|
|
252
280
|
labelNames: ["chain"] as const,
|
|
253
281
|
registers: [this.registry],
|
|
282
|
+
aggregator: "max",
|
|
254
283
|
});
|
|
255
284
|
this.ponder_sync_block_timestamp = new prometheus.Gauge({
|
|
256
285
|
name: "ponder_sync_block_timestamp",
|
|
257
286
|
help: "Closest-to-tip synced block timestamp",
|
|
258
287
|
labelNames: ["chain"] as const,
|
|
259
288
|
registers: [this.registry],
|
|
289
|
+
aggregator: "max",
|
|
260
290
|
});
|
|
261
291
|
this.ponder_sync_is_realtime = new prometheus.Gauge({
|
|
262
292
|
name: "ponder_sync_is_realtime",
|
|
263
293
|
help: "Boolean (0 or 1) indicating if the sync is realtime mode",
|
|
264
294
|
labelNames: ["chain"] as const,
|
|
265
295
|
registers: [this.registry],
|
|
296
|
+
aggregator: "max",
|
|
266
297
|
});
|
|
267
298
|
this.ponder_sync_is_complete = new prometheus.Gauge({
|
|
268
299
|
name: "ponder_sync_is_complete",
|
|
269
300
|
help: "Boolean (0 or 1) indicating if the sync has synced all blocks",
|
|
270
301
|
labelNames: ["chain"] as const,
|
|
271
302
|
registers: [this.registry],
|
|
303
|
+
aggregator: "max",
|
|
272
304
|
});
|
|
273
305
|
|
|
274
306
|
this.ponder_historical_total_blocks = new prometheus.Gauge({
|
|
@@ -276,18 +308,21 @@ export class MetricsService {
|
|
|
276
308
|
help: "Number of blocks required for the historical sync",
|
|
277
309
|
labelNames: ["chain"] as const,
|
|
278
310
|
registers: [this.registry],
|
|
311
|
+
aggregator: "max",
|
|
279
312
|
});
|
|
280
313
|
this.ponder_historical_cached_blocks = new prometheus.Gauge({
|
|
281
314
|
name: "ponder_historical_cached_blocks",
|
|
282
315
|
help: "Number of blocks that were found in the cache for the historical sync",
|
|
283
316
|
labelNames: ["chain"] as const,
|
|
284
317
|
registers: [this.registry],
|
|
318
|
+
aggregator: "max",
|
|
285
319
|
});
|
|
286
320
|
this.ponder_historical_completed_blocks = new prometheus.Gauge({
|
|
287
321
|
name: "ponder_historical_completed_blocks",
|
|
288
322
|
help: "Number of blocks that have been processed for the historical sync",
|
|
289
323
|
labelNames: ["chain", "source", "type"] as const,
|
|
290
324
|
registers: [this.registry],
|
|
325
|
+
aggregator: "max",
|
|
291
326
|
});
|
|
292
327
|
|
|
293
328
|
this.ponder_realtime_reorg_total = new prometheus.Counter({
|
|
@@ -295,6 +330,7 @@ export class MetricsService {
|
|
|
295
330
|
help: "Count of how many re-orgs have occurred",
|
|
296
331
|
labelNames: ["chain"] as const,
|
|
297
332
|
registers: [this.registry],
|
|
333
|
+
aggregator: "sum",
|
|
298
334
|
});
|
|
299
335
|
this.ponder_realtime_latency = new prometheus.Histogram({
|
|
300
336
|
name: "ponder_realtime_latency",
|
|
@@ -305,6 +341,7 @@ export class MetricsService {
|
|
|
305
341
|
1_000_000,
|
|
306
342
|
],
|
|
307
343
|
registers: [this.registry],
|
|
344
|
+
aggregator: "sum",
|
|
308
345
|
});
|
|
309
346
|
this.ponder_realtime_block_arrival_latency = new prometheus.Histogram({
|
|
310
347
|
name: "ponder_realtime_block_arrival_latency",
|
|
@@ -315,6 +352,7 @@ export class MetricsService {
|
|
|
315
352
|
1_000_000,
|
|
316
353
|
],
|
|
317
354
|
registers: [this.registry],
|
|
355
|
+
aggregator: "sum",
|
|
318
356
|
});
|
|
319
357
|
|
|
320
358
|
this.ponder_database_method_duration = new prometheus.Histogram({
|
|
@@ -323,18 +361,21 @@ export class MetricsService {
|
|
|
323
361
|
labelNames: ["service", "method"] as const,
|
|
324
362
|
buckets: alwaysIODurationMs,
|
|
325
363
|
registers: [this.registry],
|
|
364
|
+
aggregator: "sum",
|
|
326
365
|
});
|
|
327
366
|
this.ponder_database_method_error_total = new prometheus.Counter({
|
|
328
367
|
name: "ponder_database_method_error_total",
|
|
329
368
|
help: "Total number of errors encountered during database operations",
|
|
330
369
|
labelNames: ["service", "method"] as const,
|
|
331
370
|
registers: [this.registry],
|
|
371
|
+
aggregator: "sum",
|
|
332
372
|
});
|
|
333
373
|
this.ponder_http_server_active_requests = new prometheus.Gauge({
|
|
334
374
|
name: "ponder_http_server_active_requests",
|
|
335
375
|
help: "Number of active HTTP server requests",
|
|
336
376
|
labelNames: ["method", "path"] as const,
|
|
337
377
|
registers: [this.registry],
|
|
378
|
+
aggregator: "sum",
|
|
338
379
|
});
|
|
339
380
|
this.ponder_http_server_request_duration_ms = new prometheus.Histogram({
|
|
340
381
|
name: "ponder_http_server_request_duration_ms",
|
|
@@ -342,6 +383,7 @@ export class MetricsService {
|
|
|
342
383
|
labelNames: ["method", "path", "status"] as const,
|
|
343
384
|
buckets: alwaysIODurationMs,
|
|
344
385
|
registers: [this.registry],
|
|
386
|
+
aggregator: "sum",
|
|
345
387
|
});
|
|
346
388
|
this.ponder_http_server_request_size_bytes = new prometheus.Histogram({
|
|
347
389
|
name: "ponder_http_server_request_size_bytes",
|
|
@@ -349,6 +391,7 @@ export class MetricsService {
|
|
|
349
391
|
labelNames: ["method", "path", "status"] as const,
|
|
350
392
|
buckets: httpRequestSizeBytes,
|
|
351
393
|
registers: [this.registry],
|
|
394
|
+
aggregator: "sum",
|
|
352
395
|
});
|
|
353
396
|
this.ponder_http_server_response_size_bytes = new prometheus.Histogram({
|
|
354
397
|
name: "ponder_http_server_response_size_bytes",
|
|
@@ -356,6 +399,7 @@ export class MetricsService {
|
|
|
356
399
|
labelNames: ["method", "path", "status"] as const,
|
|
357
400
|
buckets: httpRequestSizeBytes,
|
|
358
401
|
registers: [this.registry],
|
|
402
|
+
aggregator: "sum",
|
|
359
403
|
});
|
|
360
404
|
|
|
361
405
|
this.ponder_rpc_request_duration = new prometheus.Histogram({
|
|
@@ -364,6 +408,7 @@ export class MetricsService {
|
|
|
364
408
|
labelNames: ["chain", "method"] as const,
|
|
365
409
|
buckets: alwaysIODurationMs,
|
|
366
410
|
registers: [this.registry],
|
|
411
|
+
aggregator: "sum",
|
|
367
412
|
});
|
|
368
413
|
|
|
369
414
|
this.ponder_rpc_request_error_total = new prometheus.Counter({
|
|
@@ -371,6 +416,7 @@ export class MetricsService {
|
|
|
371
416
|
help: "Total count of failed RPC requests",
|
|
372
417
|
labelNames: ["chain", "method"] as const,
|
|
373
418
|
registers: [this.registry],
|
|
419
|
+
aggregator: "sum",
|
|
374
420
|
});
|
|
375
421
|
|
|
376
422
|
this.ponder_postgres_query_total = new prometheus.Counter({
|
|
@@ -378,6 +424,7 @@ export class MetricsService {
|
|
|
378
424
|
help: "Total number of queries submitted to the database",
|
|
379
425
|
labelNames: ["pool"] as const,
|
|
380
426
|
registers: [this.registry],
|
|
427
|
+
aggregator: "sum",
|
|
381
428
|
});
|
|
382
429
|
|
|
383
430
|
prometheus.collectDefaultMetrics({
|
|
@@ -391,8 +438,12 @@ export class MetricsService {
|
|
|
391
438
|
* Get string representation for all metrics.
|
|
392
439
|
* @returns Metrics encoded using Prometheus v0.0.4 format.
|
|
393
440
|
*/
|
|
394
|
-
|
|
395
|
-
return
|
|
441
|
+
getMetrics() {
|
|
442
|
+
return this.registry.metrics();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async getRegistry() {
|
|
446
|
+
return this.registry;
|
|
396
447
|
}
|
|
397
448
|
|
|
398
449
|
initializeIndexingMetrics({
|
|
@@ -404,8 +455,8 @@ export class MetricsService {
|
|
|
404
455
|
}) {
|
|
405
456
|
const tables = Object.values(schemaBuild.schema).filter(isTable);
|
|
406
457
|
|
|
407
|
-
for (const
|
|
408
|
-
this.ponder_indexing_completed_events.inc({ event }, 0);
|
|
458
|
+
for (const { name: eventName } of indexingBuild.indexingFunctions) {
|
|
459
|
+
this.ponder_indexing_completed_events.inc({ event: eventName }, 0);
|
|
409
460
|
}
|
|
410
461
|
|
|
411
462
|
for (const table of tables) {
|
|
@@ -477,6 +528,168 @@ export class MetricsService {
|
|
|
477
528
|
}
|
|
478
529
|
}
|
|
479
530
|
|
|
531
|
+
type MetricsAggregationRequest = {
|
|
532
|
+
type: typeof GET_METRICS_REQ;
|
|
533
|
+
requestId: number;
|
|
534
|
+
};
|
|
535
|
+
type MetricsAggregationResponse = {
|
|
536
|
+
type: typeof GET_METRICS_RES;
|
|
537
|
+
requestId: number;
|
|
538
|
+
error?: string;
|
|
539
|
+
metrics: prometheus.MetricObjectWithValues<prometheus.MetricValue<string>>[];
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
export class AggregateMetricsService extends MetricsService {
|
|
543
|
+
workers: Worker[];
|
|
544
|
+
requests: Map<
|
|
545
|
+
number,
|
|
546
|
+
{
|
|
547
|
+
responses: prometheus.MetricObjectWithValues<
|
|
548
|
+
prometheus.MetricValue<string>
|
|
549
|
+
>[][];
|
|
550
|
+
workerIds: number[];
|
|
551
|
+
pending: number;
|
|
552
|
+
pwr: PromiseWithResolvers<void>;
|
|
553
|
+
}
|
|
554
|
+
>;
|
|
555
|
+
requestId: number;
|
|
556
|
+
mainThreadMetrics: MetricsService;
|
|
557
|
+
|
|
558
|
+
constructor(mainThreadMetrics: MetricsService, workers: Worker[]) {
|
|
559
|
+
super();
|
|
560
|
+
|
|
561
|
+
this.mainThreadMetrics = mainThreadMetrics;
|
|
562
|
+
this.workers = workers;
|
|
563
|
+
this.requests = new Map();
|
|
564
|
+
this.requestId = 0;
|
|
565
|
+
|
|
566
|
+
for (const worker of workers) {
|
|
567
|
+
worker.on("message", (message: MetricsAggregationResponse) => {
|
|
568
|
+
if (message.type === GET_METRICS_RES) {
|
|
569
|
+
const request = this.requests.get(message.requestId);
|
|
570
|
+
|
|
571
|
+
if (request === undefined) return;
|
|
572
|
+
|
|
573
|
+
if (message.error) {
|
|
574
|
+
request.pwr.reject(new Error(message.error));
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
request.responses.push(message.metrics);
|
|
579
|
+
request.workerIds.push(worker.threadId);
|
|
580
|
+
request.pending--;
|
|
581
|
+
if (request.pending === 0) {
|
|
582
|
+
request.pwr.resolve();
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
override async getMetrics() {
|
|
590
|
+
const requestId = this.requestId++;
|
|
591
|
+
const pwr = promiseWithResolvers<void>();
|
|
592
|
+
|
|
593
|
+
this.requests.set(requestId, {
|
|
594
|
+
responses: [],
|
|
595
|
+
workerIds: [],
|
|
596
|
+
pending: this.workers.length,
|
|
597
|
+
pwr,
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
for (const worker of this.workers) {
|
|
601
|
+
worker.postMessage({
|
|
602
|
+
type: GET_METRICS_REQ,
|
|
603
|
+
requestId,
|
|
604
|
+
} satisfies MetricsAggregationRequest);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
await pwr.promise;
|
|
608
|
+
|
|
609
|
+
const request = this.requests.get(requestId)!;
|
|
610
|
+
this.requests.delete(requestId);
|
|
611
|
+
|
|
612
|
+
// Sort response by worker id for consistent metrics
|
|
613
|
+
const responseIndexSort = new Array(this.workers.length)
|
|
614
|
+
.fill(0)
|
|
615
|
+
.map((_, index) => index)
|
|
616
|
+
.sort((a, b) => request.workerIds[a]! - request.workerIds[b]!);
|
|
617
|
+
|
|
618
|
+
return prometheus.AggregatorRegistry.aggregate([
|
|
619
|
+
...responseIndexSort.map((index) => request.responses[index]!),
|
|
620
|
+
await this.registry.getMetricsAsJSON(),
|
|
621
|
+
await this.mainThreadMetrics.registry.getMetricsAsJSON(),
|
|
622
|
+
]).metrics();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
override async getRegistry() {
|
|
626
|
+
const requestId = this.requestId++;
|
|
627
|
+
const pwr = promiseWithResolvers<void>();
|
|
628
|
+
|
|
629
|
+
this.requests.set(requestId, {
|
|
630
|
+
responses: [],
|
|
631
|
+
workerIds: [],
|
|
632
|
+
pending: this.workers.length,
|
|
633
|
+
pwr,
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
for (const worker of this.workers) {
|
|
637
|
+
worker.postMessage({
|
|
638
|
+
type: GET_METRICS_REQ,
|
|
639
|
+
requestId,
|
|
640
|
+
} satisfies MetricsAggregationRequest);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
await pwr.promise;
|
|
644
|
+
|
|
645
|
+
const request = this.requests.get(requestId)!;
|
|
646
|
+
this.requests.delete(requestId);
|
|
647
|
+
|
|
648
|
+
// Sort response by worker id for consistent metrics
|
|
649
|
+
const responseIndexSort = new Array(this.workers.length)
|
|
650
|
+
.fill(0)
|
|
651
|
+
.map((_, index) => index)
|
|
652
|
+
.sort((a, b) => request.workerIds[a]! - request.workerIds[b]!);
|
|
653
|
+
|
|
654
|
+
return prometheus.AggregatorRegistry.aggregate([
|
|
655
|
+
...responseIndexSort.map((index) => request.responses[index]!),
|
|
656
|
+
await this.registry.getMetricsAsJSON(),
|
|
657
|
+
await this.mainThreadMetrics.registry.getMetricsAsJSON(),
|
|
658
|
+
]) as prometheus.Registry;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// Note: `resetIndexingMetrics` and `resetApiMetrics` are never called with `AggregateMetricsService`.
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
export class IsolatedMetricsService extends MetricsService {
|
|
665
|
+
constructor() {
|
|
666
|
+
super();
|
|
667
|
+
|
|
668
|
+
if (parentPort) {
|
|
669
|
+
parentPort.on("message", (message: MetricsAggregationRequest) => {
|
|
670
|
+
if (message.type === GET_METRICS_REQ) {
|
|
671
|
+
this.registry
|
|
672
|
+
.getMetricsAsJSON()
|
|
673
|
+
.then((metrics) => {
|
|
674
|
+
parentPort!.postMessage({
|
|
675
|
+
type: GET_METRICS_RES,
|
|
676
|
+
requestId: message.requestId,
|
|
677
|
+
metrics,
|
|
678
|
+
});
|
|
679
|
+
})
|
|
680
|
+
.catch((error) => {
|
|
681
|
+
parentPort!.postMessage({
|
|
682
|
+
type: GET_METRICS_RES,
|
|
683
|
+
requestId: message.requestId,
|
|
684
|
+
error: error.message,
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
480
693
|
const extractMetric = (
|
|
481
694
|
metric: prometheus.MetricObjectWithValues<prometheus.MetricValue<"chain">>,
|
|
482
695
|
chain: string,
|
|
@@ -596,44 +809,48 @@ export async function getAppProgress(metrics: MetricsService): Promise<{
|
|
|
596
809
|
progress: number | undefined;
|
|
597
810
|
eta: number | undefined;
|
|
598
811
|
}> {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
812
|
+
// Note: `getRegistry` must be used because this function is used with "experimental_isolated" ordering.
|
|
813
|
+
const registry = await metrics.getRegistry();
|
|
814
|
+
|
|
815
|
+
const totalSecondsMetric = await registry
|
|
816
|
+
.getSingleMetric("ponder_historical_total_indexing_seconds")!
|
|
817
|
+
.get();
|
|
818
|
+
const cachedSecondsMetric = await registry
|
|
819
|
+
.getSingleMetric("ponder_historical_cached_indexing_seconds")!
|
|
820
|
+
.get();
|
|
821
|
+
const completedSecondsMetric = await registry
|
|
822
|
+
.getSingleMetric("ponder_historical_completed_indexing_seconds")!
|
|
823
|
+
.get();
|
|
824
|
+
const timestampMetric = await registry
|
|
825
|
+
.getSingleMetric("ponder_indexing_timestamp")!
|
|
826
|
+
.get();
|
|
827
|
+
|
|
828
|
+
const settingsMetric = await registry
|
|
829
|
+
.getSingleMetric("ponder_settings_info")!
|
|
830
|
+
.get();
|
|
831
|
+
const ordering: PreBuild["ordering"] | undefined = settingsMetric?.values[0]
|
|
832
|
+
?.labels.ordering as any;
|
|
833
|
+
|
|
834
|
+
switch (ordering) {
|
|
835
|
+
case undefined:
|
|
836
|
+
return {
|
|
837
|
+
mode: "backfill",
|
|
838
|
+
progress: undefined,
|
|
839
|
+
eta: undefined,
|
|
840
|
+
};
|
|
841
|
+
case "omnichain": {
|
|
842
|
+
const totalSeconds = totalSecondsMetric?.values
|
|
843
|
+
.map(({ value }) => value)
|
|
844
|
+
.reduce((prev, curr) => prev + curr, 0);
|
|
845
|
+
const cachedSeconds = cachedSecondsMetric?.values
|
|
846
|
+
.map(({ value }) => value)
|
|
847
|
+
.reduce((prev, curr) => prev + curr, 0);
|
|
848
|
+
const completedSeconds = completedSecondsMetric?.values
|
|
849
|
+
.map(({ value }) => value)
|
|
850
|
+
.reduce((prev, curr) => prev + curr, 0);
|
|
851
|
+
const timestamp = timestampMetric?.values
|
|
852
|
+
.map(({ value }) => value)
|
|
853
|
+
.reduce((prev, curr) => Math.max(prev, curr), 0);
|
|
637
854
|
|
|
638
855
|
const progress =
|
|
639
856
|
timestamp === 0
|
|
@@ -642,79 +859,92 @@ export async function getAppProgress(metrics: MetricsService): Promise<{
|
|
|
642
859
|
? 1
|
|
643
860
|
: (completedSeconds + cachedSeconds) / totalSeconds;
|
|
644
861
|
|
|
645
|
-
|
|
646
|
-
metrics.progressMetadata[chainName] = {
|
|
647
|
-
batches: [{ elapsedSeconds: 0, completedSeconds: 0 }],
|
|
648
|
-
previousTimestamp: Date.now(),
|
|
649
|
-
previousCompletedSeconds: 0,
|
|
650
|
-
rate: 0,
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
const eta: number | undefined = calculateEta(
|
|
655
|
-
metrics.progressMetadata[chainName]!,
|
|
656
|
-
totalSeconds,
|
|
657
|
-
cachedSeconds,
|
|
658
|
-
completedSeconds,
|
|
659
|
-
);
|
|
660
|
-
perChainAppProgress.push({
|
|
862
|
+
return {
|
|
661
863
|
mode: progress === 1 ? "live" : "backfill",
|
|
662
|
-
progress,
|
|
663
|
-
eta
|
|
664
|
-
|
|
864
|
+
progress: progress,
|
|
865
|
+
eta: calculateEta(
|
|
866
|
+
metrics.progressMetadata.general!,
|
|
867
|
+
totalSeconds,
|
|
868
|
+
cachedSeconds,
|
|
869
|
+
completedSeconds,
|
|
870
|
+
),
|
|
871
|
+
};
|
|
665
872
|
}
|
|
873
|
+
case "multichain":
|
|
874
|
+
case "experimental_isolated": {
|
|
875
|
+
const perChainAppProgress: Awaited<ReturnType<typeof getAppProgress>>[] =
|
|
876
|
+
[];
|
|
877
|
+
|
|
878
|
+
for (const chainName of totalSecondsMetric?.values.map(
|
|
879
|
+
({ labels }) => labels.chain as string,
|
|
880
|
+
) ?? []) {
|
|
881
|
+
const totalSeconds = extractMetric(totalSecondsMetric, chainName);
|
|
882
|
+
const cachedSeconds = extractMetric(cachedSecondsMetric, chainName);
|
|
883
|
+
const completedSeconds = extractMetric(
|
|
884
|
+
completedSecondsMetric,
|
|
885
|
+
chainName,
|
|
886
|
+
);
|
|
887
|
+
const timestamp = extractMetric(timestampMetric, chainName);
|
|
888
|
+
|
|
889
|
+
if (
|
|
890
|
+
totalSeconds === undefined ||
|
|
891
|
+
cachedSeconds === undefined ||
|
|
892
|
+
completedSeconds === undefined ||
|
|
893
|
+
timestamp === undefined
|
|
894
|
+
) {
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
666
897
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
:
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
mode: "live",
|
|
683
|
-
progress: 1,
|
|
684
|
-
eta: 0,
|
|
685
|
-
},
|
|
686
|
-
) as any;
|
|
687
|
-
} else {
|
|
688
|
-
const totalSeconds = totalSecondsMetric.values
|
|
689
|
-
.map(({ value }) => value)
|
|
690
|
-
.reduce((prev, curr) => prev + curr, 0);
|
|
691
|
-
const cachedSeconds = cachedSecondsMetric.values
|
|
692
|
-
.map(({ value }) => value)
|
|
693
|
-
.reduce((prev, curr) => prev + curr, 0);
|
|
694
|
-
const completedSeconds = completedSecondsMetric.values
|
|
695
|
-
.map(({ value }) => value)
|
|
696
|
-
.reduce((prev, curr) => prev + curr, 0);
|
|
697
|
-
const timestamp = timestampMetric.values
|
|
698
|
-
.map(({ value }) => value)
|
|
699
|
-
.reduce((prev, curr) => Math.max(prev, curr), 0);
|
|
898
|
+
const progress =
|
|
899
|
+
timestamp === 0
|
|
900
|
+
? 0
|
|
901
|
+
: totalSeconds === 0
|
|
902
|
+
? 1
|
|
903
|
+
: (completedSeconds + cachedSeconds) / totalSeconds;
|
|
904
|
+
|
|
905
|
+
if (!metrics.progressMetadata[chainName]) {
|
|
906
|
+
metrics.progressMetadata[chainName] = {
|
|
907
|
+
batches: [{ elapsedSeconds: 0, completedSeconds: 0 }],
|
|
908
|
+
previousTimestamp: Date.now(),
|
|
909
|
+
previousCompletedSeconds: 0,
|
|
910
|
+
rate: 0,
|
|
911
|
+
};
|
|
912
|
+
}
|
|
700
913
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
914
|
+
const eta: number | undefined = calculateEta(
|
|
915
|
+
metrics.progressMetadata[chainName]!,
|
|
916
|
+
totalSeconds,
|
|
917
|
+
cachedSeconds,
|
|
918
|
+
completedSeconds,
|
|
919
|
+
);
|
|
920
|
+
perChainAppProgress.push({
|
|
921
|
+
mode: progress === 1 ? "live" : "backfill",
|
|
922
|
+
progress,
|
|
923
|
+
eta,
|
|
924
|
+
});
|
|
925
|
+
}
|
|
707
926
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
927
|
+
return perChainAppProgress.reduce(
|
|
928
|
+
(prev, curr) => ({
|
|
929
|
+
mode: curr.mode === "backfill" ? curr.mode : prev.mode,
|
|
930
|
+
progress:
|
|
931
|
+
prev.progress === undefined || curr.progress === undefined
|
|
932
|
+
? undefined
|
|
933
|
+
: Math.min(prev.progress, curr.progress),
|
|
934
|
+
eta:
|
|
935
|
+
curr.progress === 1
|
|
936
|
+
? prev.eta
|
|
937
|
+
: prev.eta === undefined || curr.eta === undefined
|
|
938
|
+
? undefined
|
|
939
|
+
: Math.max(prev.eta, curr.eta),
|
|
940
|
+
}),
|
|
941
|
+
{
|
|
942
|
+
mode: "live",
|
|
943
|
+
progress: 1,
|
|
944
|
+
eta: 0,
|
|
945
|
+
},
|
|
946
|
+
);
|
|
947
|
+
}
|
|
718
948
|
}
|
|
719
949
|
}
|
|
720
950
|
|