@prisma/streams-server 0.1.1 → 0.1.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/CONTRIBUTING.md +8 -0
- package/package.json +2 -1
- package/src/app.ts +290 -17
- package/src/app_core.ts +1833 -698
- package/src/app_local.ts +144 -4
- package/src/auto_tune.ts +62 -0
- package/src/bootstrap.ts +159 -1
- package/src/concurrency_gate.ts +108 -0
- package/src/config.ts +116 -14
- package/src/db/db.ts +1201 -131
- package/src/db/schema.ts +308 -8
- package/src/foreground_activity.ts +55 -0
- package/src/index/indexer.ts +254 -124
- package/src/index/lexicon_file_cache.ts +261 -0
- package/src/index/lexicon_format.ts +93 -0
- package/src/index/lexicon_indexer.ts +789 -0
- package/src/index/secondary_indexer.ts +824 -0
- package/src/index/secondary_schema.ts +105 -0
- package/src/ingest.ts +10 -12
- package/src/manifest.ts +143 -8
- package/src/memory.ts +183 -8
- package/src/metrics.ts +15 -29
- package/src/metrics_emitter.ts +26 -3
- package/src/notifier.ts +121 -5
- package/src/objectstore/accounting.ts +92 -0
- package/src/objectstore/mock_r2.ts +1 -1
- package/src/objectstore/r2.ts +17 -1
- package/src/profiles/evlog/schema.ts +234 -0
- package/src/profiles/evlog.ts +299 -0
- package/src/profiles/generic.ts +47 -0
- package/src/profiles/index.ts +205 -0
- package/src/profiles/metrics/block_format.ts +109 -0
- package/src/profiles/metrics/normalize.ts +366 -0
- package/src/profiles/metrics/schema.ts +319 -0
- package/src/profiles/metrics.ts +85 -0
- package/src/profiles/profile.ts +225 -0
- package/src/{touch/engine.ts → profiles/stateProtocol/changes.ts} +3 -20
- package/src/profiles/stateProtocol/routes.ts +389 -0
- package/src/profiles/stateProtocol/types.ts +6 -0
- package/src/profiles/stateProtocol/validation.ts +51 -0
- package/src/profiles/stateProtocol.ts +100 -0
- package/src/read_filter.ts +468 -0
- package/src/reader.ts +2151 -164
- package/src/runtime/host_runtime.ts +5 -0
- package/src/runtime_memory.ts +200 -0
- package/src/runtime_memory_sampler.ts +235 -0
- package/src/schema/read_json.ts +43 -0
- package/src/schema/registry.ts +563 -59
- package/src/search/agg_format.ts +638 -0
- package/src/search/aggregate.ts +389 -0
- package/src/search/binary/codec.ts +162 -0
- package/src/search/binary/docset.ts +67 -0
- package/src/search/binary/restart_strings.ts +181 -0
- package/src/search/binary/varint.ts +34 -0
- package/src/search/bitset.ts +19 -0
- package/src/search/col_format.ts +382 -0
- package/src/search/col_runtime.ts +59 -0
- package/src/search/column_encoding.ts +43 -0
- package/src/search/companion_file_cache.ts +319 -0
- package/src/search/companion_format.ts +313 -0
- package/src/search/companion_manager.ts +1086 -0
- package/src/search/companion_plan.ts +218 -0
- package/src/search/fts_format.ts +423 -0
- package/src/search/fts_runtime.ts +333 -0
- package/src/search/query.ts +875 -0
- package/src/search/schema.ts +245 -0
- package/src/segment/cache.ts +93 -2
- package/src/segment/cached_segment.ts +89 -0
- package/src/segment/format.ts +108 -36
- package/src/segment/segmenter.ts +79 -5
- package/src/segment/segmenter_worker.ts +35 -6
- package/src/segment/segmenter_workers.ts +42 -12
- package/src/server.ts +150 -36
- package/src/sqlite/adapter.ts +185 -14
- package/src/sqlite/runtime_stats.ts +163 -0
- package/src/stats.ts +3 -3
- package/src/stream_size_reconciler.ts +100 -0
- package/src/touch/canonical_change.ts +7 -0
- package/src/touch/live_metrics.ts +94 -64
- package/src/touch/live_templates.ts +15 -1
- package/src/touch/manager.ts +166 -88
- package/src/touch/{interpreter_worker.ts → processor_worker.ts} +19 -14
- package/src/touch/spec.ts +95 -92
- package/src/touch/touch_journal.ts +4 -0
- package/src/touch/worker_pool.ts +8 -14
- package/src/touch/worker_protocol.ts +3 -3
- package/src/uploader.ts +77 -6
- package/src/util/bloom256.ts +2 -2
- package/src/util/byte_lru.ts +73 -0
- package/src/util/lru.ts +8 -0
- package/src/util/stream_paths.ts +19 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -38,12 +38,20 @@ bun run check:result-policy
|
|
|
38
38
|
bun test
|
|
39
39
|
bun run test:conformance:local
|
|
40
40
|
bun run test:conformance
|
|
41
|
+
bun run test:large-index-filter
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
Notes:
|
|
44
45
|
|
|
45
46
|
- `bun test` is the current fast repository baseline.
|
|
46
47
|
- `test:conformance:local` and `test:conformance` run the upstream black-box suite against local and full server modes.
|
|
48
|
+
- `test:large-index-filter` is an opt-in full-mode integration/performance test
|
|
49
|
+
that writes 1 GiB of indexed JSON data into a MockR2-backed stream and
|
|
50
|
+
measures filtered read time. The packaged script pins `16 MiB` segments to
|
|
51
|
+
match the production default. Use `DS_LARGE_INDEX_FILTER=1 bun test
|
|
52
|
+
test/large_index_filter.test.ts` directly only when you intentionally want to
|
|
53
|
+
override the segment size or other large-test settings. It is intentionally
|
|
54
|
+
excluded from the fast baseline.
|
|
47
55
|
- The current upstream conformance status is tracked in [conformance.md](./conformance.md).
|
|
48
56
|
|
|
49
57
|
## Development Expectations
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/streams-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Bun-only self-hosted Prisma Streams server.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"./package.json": "./package.json"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"@durable-streams/client": "^0.2.1",
|
|
38
39
|
"ajv": "^8.12.0",
|
|
39
40
|
"better-result": "^2.7.0",
|
|
40
41
|
"env-paths": "^3.0.0",
|
package/src/app.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Config } from "./config";
|
|
2
2
|
import { createAppCore, type App } from "./app_core";
|
|
3
3
|
import type { ObjectStore } from "./objectstore/interface";
|
|
4
|
+
import { AccountingObjectStore } from "./objectstore/accounting";
|
|
4
5
|
import { MockR2Store } from "./objectstore/mock_r2";
|
|
5
6
|
import { StreamReader } from "./reader";
|
|
6
7
|
import { SegmentDiskCache } from "./segment/cache";
|
|
@@ -10,8 +11,13 @@ import { Uploader } from "./uploader";
|
|
|
10
11
|
import { retry } from "./util/retry";
|
|
11
12
|
import { schemaObjectKey, streamHash16Hex } from "./util/stream_paths";
|
|
12
13
|
import type { StatsCollector } from "./stats";
|
|
13
|
-
import { IndexManager } from "./index/indexer";
|
|
14
|
+
import { IndexManager, type StreamIndexLookup } from "./index/indexer";
|
|
15
|
+
import { SecondaryIndexManager } from "./index/secondary_indexer";
|
|
14
16
|
import type { SchemaRegistry } from "./schema/registry";
|
|
17
|
+
import { SearchCompanionManager } from "./search/companion_manager";
|
|
18
|
+
import { LexiconIndexManager } from "./index/lexicon_indexer";
|
|
19
|
+
import { readSqliteRuntimeMemoryStats } from "./sqlite/runtime_stats";
|
|
20
|
+
import { sumRuntimeMemoryValues } from "./runtime_memory";
|
|
15
21
|
|
|
16
22
|
export type { App } from "./app_core";
|
|
17
23
|
|
|
@@ -19,29 +25,157 @@ export type CreateAppOptions = {
|
|
|
19
25
|
stats?: StatsCollector;
|
|
20
26
|
};
|
|
21
27
|
|
|
28
|
+
class CombinedIndexController implements StreamIndexLookup {
|
|
29
|
+
constructor(
|
|
30
|
+
private readonly routingIndex: IndexManager,
|
|
31
|
+
private readonly secondaryIndex: SecondaryIndexManager,
|
|
32
|
+
private readonly companionIndex: SearchCompanionManager,
|
|
33
|
+
private readonly lexiconIndex: LexiconIndexManager
|
|
34
|
+
) {}
|
|
35
|
+
|
|
36
|
+
start(): void {
|
|
37
|
+
this.routingIndex.start();
|
|
38
|
+
this.secondaryIndex.start();
|
|
39
|
+
this.companionIndex.start();
|
|
40
|
+
this.lexiconIndex.start();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
stop(): void {
|
|
44
|
+
this.routingIndex.stop();
|
|
45
|
+
this.secondaryIndex.stop();
|
|
46
|
+
this.companionIndex.stop();
|
|
47
|
+
this.lexiconIndex.stop();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
enqueue(stream: string): void {
|
|
51
|
+
this.routingIndex.enqueue(stream);
|
|
52
|
+
this.secondaryIndex.enqueue(stream);
|
|
53
|
+
this.companionIndex.enqueue(stream);
|
|
54
|
+
this.lexiconIndex.enqueue(stream);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
candidateSegmentsForRoutingKey(stream: string, keyBytes: Uint8Array) {
|
|
58
|
+
return this.routingIndex.candidateSegmentsForRoutingKey(stream, keyBytes);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
candidateSegmentsForSecondaryIndex(stream: string, indexName: string, keyBytes: Uint8Array) {
|
|
62
|
+
return this.secondaryIndex.candidateSegmentsForSecondaryIndex(stream, indexName, keyBytes);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getAggSegmentCompanion(stream: string, segmentIndex: number) {
|
|
66
|
+
return this.companionIndex.getAggSegmentCompanion(stream, segmentIndex);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getColSegmentCompanion(stream: string, segmentIndex: number) {
|
|
70
|
+
return this.companionIndex.getColSegmentCompanion(stream, segmentIndex);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getFtsSegmentCompanion(stream: string, segmentIndex: number) {
|
|
74
|
+
return this.companionIndex.getFtsSegmentCompanion(stream, segmentIndex);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getFtsSegmentCompanionWithStats(stream: string, segmentIndex: number) {
|
|
78
|
+
return this.companionIndex.getFtsSegmentCompanionWithStats(stream, segmentIndex);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getMetricsBlockSegmentCompanion(stream: string, segmentIndex: number) {
|
|
82
|
+
return this.companionIndex.getMetricsBlockSegmentCompanion(stream, segmentIndex);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
listRoutingKeysResult(stream: string, after: string | null, limit: number) {
|
|
86
|
+
return this.lexiconIndex.listRoutingKeysResult(stream, after, limit);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getLocalStorageUsage(stream: string) {
|
|
90
|
+
return {
|
|
91
|
+
routing_index_cache_bytes: this.routingIndex.getLocalCacheBytes(stream),
|
|
92
|
+
exact_index_cache_bytes: this.secondaryIndex.getLocalCacheBytes(stream),
|
|
93
|
+
companion_cache_bytes: this.companionIndex.getLocalCacheBytes(stream),
|
|
94
|
+
lexicon_index_cache_bytes: this.lexiconIndex.getLocalCacheBytes(stream),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
22
99
|
export function createApp(cfg: Config, os?: ObjectStore, opts: CreateAppOptions = {}): App {
|
|
23
100
|
return createAppCore(cfg, {
|
|
24
101
|
stats: opts.stats,
|
|
25
|
-
createRuntime: ({ config, db, stats, backpressure, metrics }) => {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: undefined;
|
|
102
|
+
createRuntime: ({ config, db, ingest, registry, notifier, stats, backpressure, metrics, memorySampler, memory, asyncIndexGate, foregroundActivity }) => {
|
|
103
|
+
const rawStore = os ?? new MockR2Store();
|
|
104
|
+
const store = new AccountingObjectStore(rawStore, db);
|
|
105
|
+
const segmenterHooks: SegmenterHooks = {
|
|
106
|
+
onSegmentSealed: (stream, payloadBytes, segmentBytes) => {
|
|
107
|
+
if (stats) stats.recordSegmentSealed(payloadBytes, segmentBytes);
|
|
108
|
+
if (backpressure) backpressure.adjustOnSeal(payloadBytes, segmentBytes);
|
|
109
|
+
notifier.notifyDetailsChanged(stream);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
36
112
|
const diskCache = new SegmentDiskCache(`${config.rootDir}/cache`, config.segmentCacheMaxBytes);
|
|
37
|
-
const uploader = new Uploader(config, db, store, diskCache, stats, backpressure);
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
113
|
+
const uploader = new Uploader(config, db, store, diskCache, stats, backpressure, undefined, memorySampler);
|
|
114
|
+
const routingIndexer = new IndexManager(
|
|
115
|
+
config,
|
|
116
|
+
db,
|
|
117
|
+
store,
|
|
118
|
+
diskCache,
|
|
119
|
+
(stream) => uploader.publishManifest(stream),
|
|
120
|
+
metrics,
|
|
121
|
+
(stream) => notifier.notifyDetailsChanged(stream),
|
|
122
|
+
memorySampler,
|
|
123
|
+
registry,
|
|
124
|
+
asyncIndexGate,
|
|
125
|
+
foregroundActivity
|
|
126
|
+
);
|
|
127
|
+
const secondaryIndexer = new SecondaryIndexManager(
|
|
128
|
+
config,
|
|
129
|
+
db,
|
|
130
|
+
store,
|
|
131
|
+
registry,
|
|
132
|
+
diskCache,
|
|
133
|
+
(stream) => uploader.publishManifest(stream),
|
|
134
|
+
(stream) => notifier.notifyDetailsChanged(stream),
|
|
135
|
+
memorySampler,
|
|
136
|
+
asyncIndexGate,
|
|
137
|
+
foregroundActivity
|
|
138
|
+
);
|
|
139
|
+
const companionIndexer = new SearchCompanionManager(
|
|
140
|
+
config,
|
|
141
|
+
db,
|
|
142
|
+
store,
|
|
143
|
+
registry,
|
|
144
|
+
diskCache,
|
|
145
|
+
(stream) => uploader.publishManifest(stream),
|
|
146
|
+
(stream) => notifier.notifyDetailsChanged(stream),
|
|
147
|
+
metrics,
|
|
148
|
+
memorySampler,
|
|
149
|
+
asyncIndexGate,
|
|
150
|
+
foregroundActivity
|
|
151
|
+
);
|
|
152
|
+
const lexiconIndexer = new LexiconIndexManager(
|
|
153
|
+
config,
|
|
154
|
+
db,
|
|
155
|
+
store,
|
|
156
|
+
diskCache,
|
|
157
|
+
(stream) => uploader.publishManifest(stream),
|
|
158
|
+
(stream) => notifier.notifyDetailsChanged(stream),
|
|
159
|
+
metrics,
|
|
160
|
+
registry,
|
|
161
|
+
asyncIndexGate,
|
|
162
|
+
foregroundActivity
|
|
163
|
+
);
|
|
164
|
+
const indexer = new CombinedIndexController(
|
|
165
|
+
routingIndexer,
|
|
166
|
+
secondaryIndexer,
|
|
167
|
+
companionIndexer,
|
|
168
|
+
lexiconIndexer
|
|
169
|
+
);
|
|
170
|
+
uploader.setHooks({
|
|
171
|
+
onSegmentsUploaded: (stream) => indexer.enqueue(stream),
|
|
172
|
+
onMetadataChanged: (stream) => notifier.notifyDetailsChanged(stream),
|
|
173
|
+
});
|
|
174
|
+
const reader = new StreamReader(config, db, store, registry, diskCache, indexer, memorySampler, memory);
|
|
41
175
|
const segmenter =
|
|
42
176
|
config.segmenterWorkers > 0
|
|
43
177
|
? new SegmenterWorkerPool(config, config.segmenterWorkers, {}, segmenterHooks)
|
|
44
|
-
: new Segmenter(config, db, {}, segmenterHooks);
|
|
178
|
+
: new Segmenter(config, db, {}, segmenterHooks, memorySampler);
|
|
45
179
|
|
|
46
180
|
return {
|
|
47
181
|
store,
|
|
@@ -49,6 +183,7 @@ export function createApp(cfg: Config, os?: ObjectStore, opts: CreateAppOptions
|
|
|
49
183
|
segmenter,
|
|
50
184
|
uploader,
|
|
51
185
|
indexer,
|
|
186
|
+
segmentDiskCache: diskCache,
|
|
52
187
|
uploadSchemaRegistry: async (stream: string, reg: SchemaRegistry): Promise<void> => {
|
|
53
188
|
const shash = streamHash16Hex(stream);
|
|
54
189
|
const key = schemaObjectKey(shash);
|
|
@@ -62,11 +197,149 @@ export function createApp(cfg: Config, os?: ObjectStore, opts: CreateAppOptions
|
|
|
62
197
|
timeoutMs: config.objectStoreTimeoutMs,
|
|
63
198
|
}
|
|
64
199
|
);
|
|
200
|
+
db.setSchemaUploadedSizeBytes(stream, body.byteLength);
|
|
201
|
+
},
|
|
202
|
+
getLocalStorageUsage: (stream: string) => ({
|
|
203
|
+
segment_cache_bytes: diskCache.bytesForObjectKeyPrefix(`streams/${streamHash16Hex(stream)}/segments/`),
|
|
204
|
+
...indexer.getLocalStorageUsage?.(stream),
|
|
205
|
+
}),
|
|
206
|
+
getRuntimeMemorySnapshot: () => {
|
|
207
|
+
const ingestMemory = ingest.getMemoryStats();
|
|
208
|
+
const segmenterMemory = segmenter.getMemoryStats?.() ?? {
|
|
209
|
+
active_builds: 0,
|
|
210
|
+
active_streams: 0,
|
|
211
|
+
active_payload_bytes: 0,
|
|
212
|
+
active_segment_bytes_estimate: 0,
|
|
213
|
+
active_rows: 0,
|
|
214
|
+
};
|
|
215
|
+
const uploaderMemory = uploader.getMemoryStats?.() ?? {
|
|
216
|
+
inflight_segments: 0,
|
|
217
|
+
inflight_segment_bytes: 0,
|
|
218
|
+
manifest_inflight_streams: 0,
|
|
219
|
+
};
|
|
220
|
+
const routingIndexMemory = routingIndexer.getMemoryStats();
|
|
221
|
+
const secondaryIndexMemory = secondaryIndexer.getMemoryStats();
|
|
222
|
+
const companionMemory = companionIndexer.getMemoryStats();
|
|
223
|
+
const lexiconMemory = lexiconIndexer.getMemoryStats();
|
|
224
|
+
const segmentDiskStats = diskCache.stats();
|
|
225
|
+
const mockR2InMemoryBytes = rawStore instanceof MockR2Store ? rawStore.memoryBytes() : 0;
|
|
226
|
+
const mockR2ObjectCount = rawStore instanceof MockR2Store ? rawStore.size() : 0;
|
|
227
|
+
const sqliteRuntime = readSqliteRuntimeMemoryStats();
|
|
228
|
+
const heapEstimates = {
|
|
229
|
+
ingest_queue_payload_bytes: ingestMemory.queuedPayloadBytes,
|
|
230
|
+
routing_run_cache_bytes: routingIndexMemory.runCacheBytes,
|
|
231
|
+
exact_run_cache_bytes: secondaryIndexMemory.runCacheBytes,
|
|
232
|
+
mock_r2_in_memory_bytes: mockR2InMemoryBytes,
|
|
233
|
+
};
|
|
234
|
+
const mappedFiles = {
|
|
235
|
+
segment_cache_mapped_bytes: segmentDiskStats.mappedBytes,
|
|
236
|
+
routing_run_disk_cache_mapped_bytes: routingIndexMemory.runDiskMappedBytes,
|
|
237
|
+
exact_run_disk_cache_mapped_bytes: secondaryIndexMemory.runDiskMappedBytes,
|
|
238
|
+
lexicon_index_mapped_bytes: lexiconMemory.mappedFileBytes,
|
|
239
|
+
companion_bundle_mapped_bytes: companionMemory.mappedFileBytes,
|
|
240
|
+
};
|
|
241
|
+
const diskCaches = {
|
|
242
|
+
segment_disk_cache_bytes: segmentDiskStats.usedBytes,
|
|
243
|
+
routing_run_disk_cache_bytes: routingIndexMemory.runDiskCacheBytes,
|
|
244
|
+
exact_run_disk_cache_bytes: secondaryIndexMemory.runDiskCacheBytes,
|
|
245
|
+
lexicon_disk_cache_bytes: lexiconMemory.fileCacheBytes,
|
|
246
|
+
companion_disk_cache_bytes: companionMemory.fileCacheBytes,
|
|
247
|
+
};
|
|
248
|
+
const pipelineBuffers = {
|
|
249
|
+
segmenter_active_payload_bytes: segmenterMemory.active_payload_bytes,
|
|
250
|
+
segmenter_active_segment_bytes_estimate: segmenterMemory.active_segment_bytes_estimate,
|
|
251
|
+
uploader_inflight_segment_bytes: uploaderMemory.inflight_segment_bytes,
|
|
252
|
+
};
|
|
253
|
+
const sqliteRuntimeBytes = {
|
|
254
|
+
sqlite_memory_used_bytes: sqliteRuntime.memory_used_bytes,
|
|
255
|
+
sqlite_memory_highwater_bytes: sqliteRuntime.memory_highwater_bytes,
|
|
256
|
+
sqlite_pagecache_overflow_bytes: sqliteRuntime.pagecache_overflow_bytes,
|
|
257
|
+
sqlite_pagecache_overflow_highwater_bytes: sqliteRuntime.pagecache_overflow_highwater_bytes,
|
|
258
|
+
};
|
|
259
|
+
const configuredBudgets = {
|
|
260
|
+
sqlite_cache_budget_bytes: config.sqliteCacheBytes,
|
|
261
|
+
worker_sqlite_cache_budget_bytes: config.workerSqliteCacheBytes,
|
|
262
|
+
segment_cache_budget_bytes: config.segmentCacheMaxBytes,
|
|
263
|
+
routing_run_cache_budget_bytes: config.indexRunMemoryCacheBytes,
|
|
264
|
+
routing_run_disk_cache_budget_bytes: config.indexRunCacheMaxBytes,
|
|
265
|
+
exact_run_cache_budget_bytes: config.indexRunMemoryCacheBytes,
|
|
266
|
+
exact_run_disk_cache_budget_bytes: config.indexRunCacheMaxBytes,
|
|
267
|
+
lexicon_disk_cache_budget_bytes: config.lexiconIndexCacheMaxBytes,
|
|
268
|
+
companion_disk_cache_budget_bytes: config.searchCompanionFileCacheMaxBytes,
|
|
269
|
+
};
|
|
270
|
+
const counts = {
|
|
271
|
+
ingest_queue_requests: ingestMemory.queuedRequests,
|
|
272
|
+
segment_disk_cache_entries: segmentDiskStats.entryCount,
|
|
273
|
+
segment_mapped_files: segmentDiskStats.mappedEntryCount,
|
|
274
|
+
segment_pinned_files: segmentDiskStats.pinnedEntryCount,
|
|
275
|
+
routing_run_cache_entries: routingIndexMemory.runCacheEntries,
|
|
276
|
+
routing_run_disk_cache_entries: routingIndexMemory.runDiskCacheEntries,
|
|
277
|
+
routing_run_disk_cache_mapped_entries: routingIndexMemory.runDiskMappedEntries,
|
|
278
|
+
routing_run_disk_cache_pinned_entries: routingIndexMemory.runDiskPinnedEntries,
|
|
279
|
+
exact_run_cache_entries: secondaryIndexMemory.runCacheEntries,
|
|
280
|
+
exact_run_disk_cache_entries: secondaryIndexMemory.runDiskCacheEntries,
|
|
281
|
+
exact_run_disk_cache_mapped_entries: secondaryIndexMemory.runDiskMappedEntries,
|
|
282
|
+
exact_run_disk_cache_pinned_entries: secondaryIndexMemory.runDiskPinnedEntries,
|
|
283
|
+
secondary_index_stream_idle_ticks: secondaryIndexMemory.streamIdleTickEntries,
|
|
284
|
+
lexicon_cached_files: lexiconMemory.fileCacheEntries,
|
|
285
|
+
lexicon_mapped_files: lexiconMemory.mappedFileEntries,
|
|
286
|
+
lexicon_pinned_files: lexiconMemory.pinnedFileEntries,
|
|
287
|
+
companion_cached_files: companionMemory.fileCacheEntries,
|
|
288
|
+
companion_mapped_files: companionMemory.mappedFileEntries,
|
|
289
|
+
companion_pinned_files: companionMemory.pinnedFileEntries,
|
|
290
|
+
mock_r2_object_count: mockR2ObjectCount,
|
|
291
|
+
mock_r2_in_memory_bytes: mockR2InMemoryBytes,
|
|
292
|
+
pending_upload_segments: uploader.countSegmentsWaiting(),
|
|
293
|
+
uploader_inflight_segments: uploaderMemory.inflight_segments,
|
|
294
|
+
uploader_manifest_inflight_streams: uploaderMemory.manifest_inflight_streams,
|
|
295
|
+
segmenter_active_builds: segmenterMemory.active_builds,
|
|
296
|
+
segmenter_active_streams: segmenterMemory.active_streams,
|
|
297
|
+
segmenter_active_rows: segmenterMemory.active_rows,
|
|
298
|
+
sqlite_pagecache_used_slots: sqliteRuntime.pagecache_used_slots,
|
|
299
|
+
sqlite_pagecache_used_slots_highwater: sqliteRuntime.pagecache_used_slots_highwater,
|
|
300
|
+
sqlite_malloc_count: sqliteRuntime.malloc_count,
|
|
301
|
+
sqlite_malloc_count_highwater: sqliteRuntime.malloc_count_highwater,
|
|
302
|
+
sqlite_open_connections: sqliteRuntime.open_connections,
|
|
303
|
+
sqlite_prepared_statements: sqliteRuntime.prepared_statements,
|
|
304
|
+
};
|
|
305
|
+
return {
|
|
306
|
+
subsystems: {
|
|
307
|
+
heap_estimates: heapEstimates,
|
|
308
|
+
mapped_files: mappedFiles,
|
|
309
|
+
disk_caches: diskCaches,
|
|
310
|
+
configured_budgets: configuredBudgets,
|
|
311
|
+
pipeline_buffers: pipelineBuffers,
|
|
312
|
+
sqlite_runtime: sqliteRuntimeBytes,
|
|
313
|
+
counts,
|
|
314
|
+
},
|
|
315
|
+
totals: {
|
|
316
|
+
heap_estimate_bytes: sumRuntimeMemoryValues(heapEstimates),
|
|
317
|
+
mapped_file_bytes: sumRuntimeMemoryValues(mappedFiles),
|
|
318
|
+
disk_cache_bytes: sumRuntimeMemoryValues(diskCaches),
|
|
319
|
+
configured_budget_bytes: sumRuntimeMemoryValues(configuredBudgets),
|
|
320
|
+
pipeline_buffer_bytes: sumRuntimeMemoryValues(pipelineBuffers),
|
|
321
|
+
sqlite_runtime_bytes: sumRuntimeMemoryValues(sqliteRuntimeBytes),
|
|
322
|
+
},
|
|
323
|
+
};
|
|
65
324
|
},
|
|
66
325
|
start: () => {
|
|
67
326
|
segmenter.start();
|
|
68
327
|
uploader.start();
|
|
69
328
|
indexer.start();
|
|
329
|
+
setTimeout(() => {
|
|
330
|
+
try {
|
|
331
|
+
let offset = 0;
|
|
332
|
+
const pageSize = 1000;
|
|
333
|
+
for (;;) {
|
|
334
|
+
const streams = db.listStreams(pageSize, offset);
|
|
335
|
+
for (const row of streams) indexer.enqueue(row.stream);
|
|
336
|
+
if (streams.length < pageSize) break;
|
|
337
|
+
offset += streams.length;
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
// App may have been closed before the startup catch-up kickoff ran.
|
|
341
|
+
}
|
|
342
|
+
}, 0);
|
|
70
343
|
},
|
|
71
344
|
};
|
|
72
345
|
},
|