flatsql 0.4.3 → 1.0.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/README.md +116 -6
- package/dist/artifacts/builder.d.ts +31 -0
- package/dist/artifacts/builder.d.ts.map +1 -0
- package/dist/artifacts/builder.js +514 -0
- package/dist/artifacts/builder.js.map +1 -0
- package/dist/artifacts/demo-extractors.d.ts +15 -0
- package/dist/artifacts/demo-extractors.d.ts.map +1 -0
- package/dist/artifacts/demo-extractors.js +238 -0
- package/dist/artifacts/demo-extractors.js.map +1 -0
- package/dist/artifacts/index.d.ts +5 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/standalone-builder.d.ts +62 -0
- package/dist/artifacts/standalone-builder.d.ts.map +1 -0
- package/dist/artifacts/standalone-builder.js +144 -0
- package/dist/artifacts/standalone-builder.js.map +1 -0
- package/dist/artifacts/transport.d.ts +5 -0
- package/dist/artifacts/transport.d.ts.map +1 -0
- package/dist/artifacts/transport.js +45 -0
- package/dist/artifacts/transport.js.map +1 -0
- package/dist/artifacts/types.d.ts +34 -0
- package/dist/artifacts/types.d.ts.map +1 -0
- package/dist/artifacts/types.js +2 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/worker-client.d.ts +32 -0
- package/dist/artifacts/worker-client.d.ts.map +1 -0
- package/dist/artifacts/worker-client.js +415 -0
- package/dist/artifacts/worker-client.js.map +1 -0
- package/dist/btree/btree.d.ts.map +1 -1
- package/dist/btree/btree.js +13 -14
- package/dist/btree/btree.js.map +1 -1
- package/dist/core/database.d.ts +2 -0
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +18 -0
- package/dist/core/database.js.map +1 -1
- package/dist/core/table-store.d.ts +1 -0
- package/dist/core/table-store.d.ts.map +1 -1
- package/dist/core/table-store.js +31 -0
- package/dist/core/table-store.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/response/artifact.d.ts +5 -0
- package/dist/response/artifact.d.ts.map +1 -0
- package/dist/response/artifact.js +102 -0
- package/dist/response/artifact.js.map +1 -0
- package/dist/response/cache-key.d.ts +6 -0
- package/dist/response/cache-key.d.ts.map +1 -0
- package/dist/response/cache-key.js +114 -0
- package/dist/response/cache-key.js.map +1 -0
- package/dist/response/index.d.ts +5 -0
- package/dist/response/index.d.ts.map +1 -0
- package/dist/response/index.js +5 -0
- package/dist/response/index.js.map +1 -0
- package/dist/response/memory-cache.d.ts +17 -0
- package/dist/response/memory-cache.d.ts.map +1 -0
- package/dist/response/memory-cache.js +76 -0
- package/dist/response/memory-cache.js.map +1 -0
- package/dist/response/types.d.ts +51 -0
- package/dist/response/types.d.ts.map +1 -0
- package/dist/response/types.js +2 -0
- package/dist/response/types.js.map +1 -0
- package/dist/standalone/index.d.ts +3 -0
- package/dist/standalone/index.d.ts.map +1 -0
- package/dist/standalone/index.js +3 -0
- package/dist/standalone/index.js.map +1 -0
- package/dist/standalone/process-client.d.ts +85 -0
- package/dist/standalone/process-client.d.ts.map +1 -0
- package/dist/standalone/process-client.js +537 -0
- package/dist/standalone/process-client.js.map +1 -0
- package/dist/standalone/wasmedge-runner.d.ts +19 -0
- package/dist/standalone/wasmedge-runner.d.ts.map +1 -0
- package/dist/standalone/wasmedge-runner.js +108 -0
- package/dist/standalone/wasmedge-runner.js.map +1 -0
- package/dist/stress/aggregate.d.ts +3 -0
- package/dist/stress/aggregate.d.ts.map +1 -0
- package/dist/stress/aggregate.js +61 -0
- package/dist/stress/aggregate.js.map +1 -0
- package/dist/stress/docker-compose.d.ts +17 -0
- package/dist/stress/docker-compose.d.ts.map +1 -0
- package/dist/stress/docker-compose.js +156 -0
- package/dist/stress/docker-compose.js.map +1 -0
- package/dist/stress/index.d.ts +11 -0
- package/dist/stress/index.d.ts.map +1 -0
- package/dist/stress/index.js +11 -0
- package/dist/stress/index.js.map +1 -0
- package/dist/stress/metrics.d.ts +3 -0
- package/dist/stress/metrics.d.ts.map +1 -0
- package/dist/stress/metrics.js +83 -0
- package/dist/stress/metrics.js.map +1 -0
- package/dist/stress/native-publish-event-workload.d.ts +3 -0
- package/dist/stress/native-publish-event-workload.d.ts.map +1 -0
- package/dist/stress/native-publish-event-workload.js +455 -0
- package/dist/stress/native-publish-event-workload.js.map +1 -0
- package/dist/stress/production-gate.d.ts +4 -0
- package/dist/stress/production-gate.d.ts.map +1 -0
- package/dist/stress/production-gate.js +12 -0
- package/dist/stress/production-gate.js.map +1 -0
- package/dist/stress/publish-event-workload.d.ts +3 -0
- package/dist/stress/publish-event-workload.d.ts.map +1 -0
- package/dist/stress/publish-event-workload.js +467 -0
- package/dist/stress/publish-event-workload.js.map +1 -0
- package/dist/stress/report.d.ts +3 -0
- package/dist/stress/report.d.ts.map +1 -0
- package/dist/stress/report.js +174 -0
- package/dist/stress/report.js.map +1 -0
- package/dist/stress/sds-discovery.d.ts +4 -0
- package/dist/stress/sds-discovery.d.ts.map +1 -0
- package/dist/stress/sds-discovery.js +40 -0
- package/dist/stress/sds-discovery.js.map +1 -0
- package/dist/stress/smoke-runner.d.ts +3 -0
- package/dist/stress/smoke-runner.d.ts.map +1 -0
- package/dist/stress/smoke-runner.js +63 -0
- package/dist/stress/smoke-runner.js.map +1 -0
- package/dist/stress/types.d.ts +219 -0
- package/dist/stress/types.d.ts.map +1 -0
- package/dist/stress/types.js +2 -0
- package/dist/stress/types.js.map +1 -0
- package/dist/stress/workload.d.ts +6 -0
- package/dist/stress/workload.d.ts.map +1 -0
- package/dist/stress/workload.js +144 -0
- package/dist/stress/workload.js.map +1 -0
- package/docs/agents/response-artifacts.md +65 -0
- package/docs/response-artifacts.md +86 -0
- package/package.json +36 -6
- package/scripts/stress-docker.sh +279 -0
- package/sdm/flatsql-spatial.wasm +0 -0
- package/stress/docker/Dockerfile +11 -0
- package/stress/docker/docker-compose.yml +51 -0
- package/stress/sds/aggregate.mjs +97 -0
- package/stress/sds/run.mjs +105 -0
- package/stress/sds/write-compose.mjs +96 -0
- package/wasm/flatsql-artifact.worker.js +847 -0
- package/wasm/flatsql-wasi.wasm +0 -0
- package/wasm/flatsql.js +2 -16
- package/wasm/flatsql.wasm +0 -0
- package/wasm/index.d.ts +117 -2
- package/wasm/index.js +410 -42
- package/wasm/native/flatsql_wasmedge_runner.cpp +858 -0
- package/wasm/standalone.d.ts +91 -0
- package/wasm/standalone.js +740 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export const DEFAULT_USE_CASES = [
|
|
2
|
+
{
|
|
3
|
+
id: 'schema-sweep',
|
|
4
|
+
label: 'SDS schema sweep',
|
|
5
|
+
operation: 'schema-parse',
|
|
6
|
+
description: 'Discover every SDS FlatBuffer schema and record compatibility metadata.',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
id: 'bulk-streaming-ingest',
|
|
10
|
+
label: 'Bulk streaming ingest',
|
|
11
|
+
operation: 'stream-ingest',
|
|
12
|
+
description: 'Stream generated FlatBuffers in size-prefixed batches.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'hot-file-id-cache',
|
|
16
|
+
label: 'Hot FILE_ID query cache',
|
|
17
|
+
operation: 'query-template',
|
|
18
|
+
description: 'Repeat the same PNM/DPM-style FILE_ID lookup to measure cache behavior.',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'cold-file-id-fanout',
|
|
22
|
+
label: 'Cold FILE_ID fanout',
|
|
23
|
+
operation: 'query-template',
|
|
24
|
+
description: 'Fan out mostly unique FILE_ID lookups and measure cache churn.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'mixed-hot-cold-query',
|
|
28
|
+
label: 'Mixed hot/cold query distribution',
|
|
29
|
+
operation: 'query-template',
|
|
30
|
+
description: 'Run a skewed query mix with hot and long-tail FILE_ID values.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'raw-flatbuffer-retrieval',
|
|
34
|
+
label: 'Raw FlatBuffer retrieval',
|
|
35
|
+
operation: 'raw-flatbuffer',
|
|
36
|
+
description: 'Return original FlatBuffer bytes through indexed lookup paths.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'sql-projection-query',
|
|
40
|
+
label: 'SQL projection query',
|
|
41
|
+
operation: 'parameterized-sql',
|
|
42
|
+
description: 'Return a narrow SQL projection to compare against binary payload transfer.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'raw-sql-query',
|
|
46
|
+
label: 'Raw SQL query',
|
|
47
|
+
operation: 'raw-sql',
|
|
48
|
+
description: 'Execute untemplated SQL and compare request overhead with query templates.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'large-result-query',
|
|
52
|
+
label: 'Large result query',
|
|
53
|
+
operation: 'large-result',
|
|
54
|
+
description: 'Return more rows than the result-cache row cap and measure transport cost.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'node-fanout-query',
|
|
58
|
+
label: 'Node fanout query',
|
|
59
|
+
operation: 'fanout-query',
|
|
60
|
+
description: 'Send one logical query across many nodes and measure tail latency.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'backfill-sync',
|
|
64
|
+
label: 'Backfill sync',
|
|
65
|
+
operation: 'backfill-stream',
|
|
66
|
+
description: 'Bootstrap a node by streaming records from another source.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'restart-rebuild',
|
|
70
|
+
label: 'Restart and rebuild',
|
|
71
|
+
operation: 'restart-rebuild',
|
|
72
|
+
description: 'Restart a node and measure rebuild or reload behavior.',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'cache-invalidation-churn',
|
|
76
|
+
label: 'Cache invalidation churn',
|
|
77
|
+
operation: 'ingest-query-churn',
|
|
78
|
+
description: 'Alternate ingest and hot queries to expose broad invalidation cost.',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'bandwidth-constrained-streaming',
|
|
82
|
+
label: 'Bandwidth-constrained streaming',
|
|
83
|
+
operation: 'throttled-stream',
|
|
84
|
+
description: 'Measure chunked streaming behavior under an artificial transport limit.',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'sds-domain-query-pack',
|
|
88
|
+
label: 'SDS domain query pack',
|
|
89
|
+
operation: 'domain-query',
|
|
90
|
+
description: 'Exercise named space-domain lookups such as catalog, ephemeris, sensor, and weather queries.',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'udl-style-api-shape',
|
|
94
|
+
label: 'UDL-style API comparison shape',
|
|
95
|
+
operation: 'api-shape',
|
|
96
|
+
description: 'Run centralized API-shaped requests without calling an external UDL service.',
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
export function normalizeStressRunConfig(config = {}) {
|
|
100
|
+
const mode = config.mode ?? 'smoke';
|
|
101
|
+
return {
|
|
102
|
+
mode,
|
|
103
|
+
runId: config.runId ?? `sds-${mode}-${Date.now()}`,
|
|
104
|
+
nodeCount: config.nodeCount ?? (mode === 'full' ? 100 : 2),
|
|
105
|
+
nodeIdOffset: config.nodeIdOffset ?? 0,
|
|
106
|
+
nodeStorageGb: config.nodeStorageGb ?? (mode === 'full' ? 1 : 0.01),
|
|
107
|
+
recordsPerNode: config.recordsPerNode ?? (mode === 'full' ? 20_000 : 100),
|
|
108
|
+
batchBytes: config.batchBytes ?? 1024 * 1024,
|
|
109
|
+
queryConcurrency: config.queryConcurrency ?? (mode === 'full' ? 64 : 4),
|
|
110
|
+
hotQueryRatio: config.hotQueryRatio ?? 0.9,
|
|
111
|
+
runtime: config.runtime ?? 'standalone',
|
|
112
|
+
transport: config.transport ?? 'in-process',
|
|
113
|
+
nodeIsolation: config.nodeIsolation ?? 'logical',
|
|
114
|
+
seed: config.seed ?? 0x5d5,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export function buildNodeAssignments(schemas, config) {
|
|
118
|
+
const schemaNames = schemas.map((schema) => schema.name);
|
|
119
|
+
return Array.from({ length: config.nodeCount }, (_, localNodeIndex) => {
|
|
120
|
+
const nodeId = config.nodeIdOffset + localNodeIndex;
|
|
121
|
+
const assigned = schemaNames.filter((_, index) => index % config.nodeCount === localNodeIndex);
|
|
122
|
+
if (assigned.length === 0 && schemaNames.length > 0) {
|
|
123
|
+
assigned.push(schemaNames[nodeId % schemaNames.length]);
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
nodeId,
|
|
127
|
+
storageGb: config.nodeStorageGb,
|
|
128
|
+
schemas: assigned,
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
export function buildWorkloadManifest(config, schemas) {
|
|
133
|
+
const normalized = normalizeStressRunConfig(config);
|
|
134
|
+
const sortedSchemas = [...schemas].sort((left, right) => left.name.localeCompare(right.name));
|
|
135
|
+
return {
|
|
136
|
+
...normalized,
|
|
137
|
+
createdAt: new Date().toISOString(),
|
|
138
|
+
schemaCount: sortedSchemas.length,
|
|
139
|
+
schemas: sortedSchemas,
|
|
140
|
+
useCases: DEFAULT_USE_CASES,
|
|
141
|
+
assignments: buildNodeAssignments(sortedSchemas, normalized),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=workload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload.js","sourceRoot":"","sources":["../../src/stress/workload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Agent Guide: Response Bandwidth
|
|
2
|
+
|
|
3
|
+
Use this guide when modifying FlatSQL response caching, SDS stress tests, or Space Data Network FILE_ID behavior.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Do not add FlatSQL-specific fields or annotations to canonical SDS schemas.
|
|
8
|
+
- Treat `FILE_ID` as a Space Data Network publish-event policy key.
|
|
9
|
+
- Use runtime indexes or external SDN index profiles for lookup speed.
|
|
10
|
+
- Measure response bytes separately from query latency and cache hits.
|
|
11
|
+
- Prefer raw FlatBuffer artifacts for repeated high-volume responses.
|
|
12
|
+
- Tune native query-template cache limits with `configureQueryCache({ maxEntries, maxRows })` when hot FILE_ID traffic needs more than the defaults.
|
|
13
|
+
|
|
14
|
+
## Library Responsibilities
|
|
15
|
+
|
|
16
|
+
FlatSQL response bandwidth work belongs in these primitives:
|
|
17
|
+
|
|
18
|
+
- native `buildResponseArtifactCacheKey(...)` bindings for deterministic query/result cache keys
|
|
19
|
+
- `createQueryResponseArtifact(...)` for immutable byte artifacts
|
|
20
|
+
- `getResponseArtifactChunk(...)` for range-addressable chunk reads
|
|
21
|
+
- `MemoryResponseArtifactCache.getOrCreateByKey(...)` for bounded process-local artifact reuse with native keys
|
|
22
|
+
|
|
23
|
+
Deployment code is responsible for CDN, browser Cache API, WasmEdge host filesystem cache, auth, quotas, routing, and regional replication.
|
|
24
|
+
|
|
25
|
+
## Required Tests
|
|
26
|
+
|
|
27
|
+
When changing response artifacts, run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm test -- --runInBand --runTestsByPath test/response-artifact.test.ts
|
|
31
|
+
npm test -- --runInBand --runTestsByPath test/wasm-query-params.test.ts test/standalone-shim.test.ts test/standalone-artifact-builder.test.ts test/wasmedge-runner.test.ts
|
|
32
|
+
npm test -- --runInBand --runTestsByPath test/stress-harness.test.ts
|
|
33
|
+
npm run build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Before claiming production readiness, also run:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm test -- --runInBand
|
|
40
|
+
npm run stress:sds:full-config -- --run-id sds-full-config-check
|
|
41
|
+
docker compose -f stress/results/sds-full-config-check/docker-compose.full.yml config
|
|
42
|
+
git diff --check
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## SDS Stress Interpretation
|
|
46
|
+
|
|
47
|
+
The SDS harness reports measured events. A cache hit is not enough. If `responseBytes` remains high, repeated clients are still consuming bandwidth unless the response artifact is served from edge/browser/WasmEdge host cache.
|
|
48
|
+
|
|
49
|
+
For hot publish events, look at:
|
|
50
|
+
|
|
51
|
+
- `hot-file-id-cache.responseBytes`
|
|
52
|
+
- `raw-flatbuffer-retrieval.responseBytes`
|
|
53
|
+
- `sql-projection-query.responseBytes`
|
|
54
|
+
- `bulk-streaming-ingest.requestBytes`
|
|
55
|
+
- aggregate `ingestRecordsPerSecond` and `minNodeIngestRecordsPerSecond`; every node must stay at or above 75 fps for production readiness
|
|
56
|
+
- `bandwidth-constrained-streaming.requestBytes`
|
|
57
|
+
- per-node `storageBytes` and storage fill percentage; every node must reach at least 95% of its configured storage target
|
|
58
|
+
|
|
59
|
+
## Common Mistakes
|
|
60
|
+
|
|
61
|
+
- Calling a run successful because query latency improved while response bytes remain unchanged.
|
|
62
|
+
- Requiring fields like `file_identifier`, `indexed`, `key`, or `id` in SDS schemas.
|
|
63
|
+
- Returning JSON for large repeated query results when raw FlatBuffer bytes are acceptable.
|
|
64
|
+
- Building a process-local cache and assuming it solves 2M-user egress.
|
|
65
|
+
- Omitting schema version, projection, format, or publish-event key from a cache key.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Response Artifacts
|
|
2
|
+
|
|
3
|
+
FlatSQL reduces response bandwidth by producing cacheable response artifacts. The library owns deterministic byte output, cache keys, hashes, ETags, and chunk metadata. Deployment infrastructure owns CDN placement, global invalidation, routing, authorization, and quotas.
|
|
4
|
+
|
|
5
|
+
## Boundary
|
|
6
|
+
|
|
7
|
+
FlatSQL should do:
|
|
8
|
+
|
|
9
|
+
- build deterministic cache keys in the C++/WASM core from query shape, schema version, format, projection, params, and publish-event key
|
|
10
|
+
- encode raw FlatBuffer query results as size-prefixed byte streams
|
|
11
|
+
- encode JSON results only when callers explicitly request JSON
|
|
12
|
+
- produce content hashes and ETags for immutable artifacts
|
|
13
|
+
- split artifacts into range-addressable chunks
|
|
14
|
+
- expose small process-local caches for repeated query artifacts
|
|
15
|
+
|
|
16
|
+
FlatSQL should not do:
|
|
17
|
+
|
|
18
|
+
- add database-specific annotations to canonical SDS schemas
|
|
19
|
+
- implement a CDN or global cache-invalidation service
|
|
20
|
+
- decide authorization or tenant-specific cache policy
|
|
21
|
+
- route users to regions or nodes
|
|
22
|
+
- hide response byte cost behind a query-cache hit counter
|
|
23
|
+
|
|
24
|
+
## Recommended FILE_ID Flow
|
|
25
|
+
|
|
26
|
+
For Space Data Network publish events, `FILE_ID` is a network policy key, not a schema requirement.
|
|
27
|
+
|
|
28
|
+
1. Ingest records for a publish event.
|
|
29
|
+
2. Apply `FILE_ID` indexes through runtime policy or SDN index profiles.
|
|
30
|
+
3. Query the publish event with a stable projection and format.
|
|
31
|
+
4. Create a response artifact.
|
|
32
|
+
5. Serve the artifact by `ETag` or content hash from edge, browser, WasmEdge host storage, or a CDN.
|
|
33
|
+
6. Recompute only when the publish event, schema version, projection, or format changes.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import {
|
|
37
|
+
createQueryResponseArtifact,
|
|
38
|
+
MemoryResponseArtifactCache,
|
|
39
|
+
} from 'flatsql/response';
|
|
40
|
+
import initFlatSQL from 'flatsql/wasm';
|
|
41
|
+
|
|
42
|
+
const flatsql = await initFlatSQL();
|
|
43
|
+
const sql = "SELECT _data FROM PublishEventRecord WHERE FILE_ID = ?";
|
|
44
|
+
const cacheKey = flatsql.buildResponseArtifactCacheKey('PublishEventRecord', '1', sql, {
|
|
45
|
+
format: 'raw-flatbuffer-stream',
|
|
46
|
+
publishEventKey: 'publish-1',
|
|
47
|
+
projection: ['_data'],
|
|
48
|
+
params: ['publish-1'],
|
|
49
|
+
});
|
|
50
|
+
const result = db.query(sql);
|
|
51
|
+
const cache = new MemoryResponseArtifactCache();
|
|
52
|
+
|
|
53
|
+
const artifact = cache.getOrCreateByKey(cacheKey, () => createQueryResponseArtifact(result, {
|
|
54
|
+
schemaName: 'PublishEventRecord',
|
|
55
|
+
schemaVersion: 1,
|
|
56
|
+
sql,
|
|
57
|
+
params: ['publish-1'],
|
|
58
|
+
format: 'raw-flatbuffer-stream',
|
|
59
|
+
publishEventKey: 'publish-1',
|
|
60
|
+
projection: ['_data'],
|
|
61
|
+
cacheKey,
|
|
62
|
+
chunkBytes: 1024 * 1024,
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
console.log(cacheKey);
|
|
66
|
+
console.log(artifact.metadata.etag);
|
|
67
|
+
console.log(artifact.metadata.chunks);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Production Checks
|
|
71
|
+
|
|
72
|
+
Before relying on response artifacts in production:
|
|
73
|
+
|
|
74
|
+
- verify `cacheKey` includes every dimension that can change bytes
|
|
75
|
+
- verify browser and WasmEdge runtimes produce the same native response cache key
|
|
76
|
+
- prefer `raw-flatbuffer-stream` for high-volume SDS responses
|
|
77
|
+
- verify `responseBytes` and `flatbufferBytes`, not only query latency
|
|
78
|
+
- tune native `configureQueryCache({ maxEntries, maxRows })` limits for hot FILE_ID query templates
|
|
79
|
+
- set chunk sizes based on edge/cache/range-request behavior
|
|
80
|
+
- cap in-process caches with `maxEntries` and `maxBytes`
|
|
81
|
+
- keep authorization outside shared immutable artifacts unless all callers are allowed to read identical bytes
|
|
82
|
+
- test hot `FILE_ID` traffic separately from cold fanout
|
|
83
|
+
|
|
84
|
+
## Runtime Notes
|
|
85
|
+
|
|
86
|
+
Browser deployments should call the native `buildResponseArtifactCacheKey(...)` binding through `flatsql/wasm` or `flatsql/standalone`, then map artifact metadata to HTTP cache headers and the browser Cache API where appropriate. WasmEdge deployments should call the same binding through `flatsql/artifacts/standalone` and map artifacts to host filesystem or edge-local object cache. FlatSQL response artifacts are intentionally plain bytes plus metadata so either runtime can use the same cache key and ETag semantics.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flatsql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "SQL queries over raw FlatBuffer storage - zero conversion, real-time indexing, pure streaming",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,6 +18,22 @@
|
|
|
18
18
|
"types": "./wasm/wasi.d.ts",
|
|
19
19
|
"import": "./wasm/wasi.js"
|
|
20
20
|
},
|
|
21
|
+
"./standalone": {
|
|
22
|
+
"types": "./wasm/standalone.d.ts",
|
|
23
|
+
"import": "./wasm/standalone.js"
|
|
24
|
+
},
|
|
25
|
+
"./artifacts/standalone": {
|
|
26
|
+
"types": "./dist/artifacts/standalone-builder.d.ts",
|
|
27
|
+
"import": "./dist/artifacts/standalone-builder.js"
|
|
28
|
+
},
|
|
29
|
+
"./response": {
|
|
30
|
+
"types": "./dist/response/index.d.ts",
|
|
31
|
+
"import": "./dist/response/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./standalone/wasmedge": {
|
|
34
|
+
"types": "./dist/standalone/index.d.ts",
|
|
35
|
+
"import": "./dist/standalone/index.js"
|
|
36
|
+
},
|
|
21
37
|
"./wasi.wasm": "./wasm/flatsql-wasi.wasm",
|
|
22
38
|
"./sdm": {
|
|
23
39
|
"types": "./sdm/index.d.ts",
|
|
@@ -29,30 +45,43 @@
|
|
|
29
45
|
"dist",
|
|
30
46
|
"wasm/*.js",
|
|
31
47
|
"wasm/*.wasm",
|
|
48
|
+
"wasm/*.json",
|
|
32
49
|
"wasm/*.d.ts",
|
|
50
|
+
"wasm/native/*.cpp",
|
|
33
51
|
"sdm/*.js",
|
|
34
52
|
"sdm/*.wasm",
|
|
35
53
|
"sdm/*.d.ts",
|
|
36
54
|
"sdm/*.json",
|
|
55
|
+
"scripts/stress-docker.sh",
|
|
56
|
+
"stress/docker/*",
|
|
57
|
+
"stress/sds/*.mjs",
|
|
58
|
+
"docs/response-artifacts.md",
|
|
59
|
+
"docs/agents/*.md",
|
|
37
60
|
"README.md",
|
|
38
61
|
"LICENSE"
|
|
39
62
|
],
|
|
40
63
|
"scripts": {
|
|
41
64
|
"build": "tsc",
|
|
42
65
|
"build:wasm": "bash scripts/build-wasm.sh",
|
|
43
|
-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
66
|
+
"test": "node --experimental-wasm-exnref --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
44
67
|
"test:wasm": "node wasm/test-bulk-ingest.mjs",
|
|
45
68
|
"dev": "tsc --watch",
|
|
46
69
|
"serve": "vite docs --port 8081",
|
|
47
70
|
"bench": "node bench/flatsql-perf.mjs",
|
|
48
71
|
"bench:perf": "node bench/flatsql-perf.mjs",
|
|
49
72
|
"bench:perf:profile": "node bench/flatsql-perf.mjs --profile",
|
|
50
|
-
"prepublishOnly": "npm run build",
|
|
73
|
+
"prepublishOnly": "npm run build && npm run test:wasi && npm run test:wasmedge && npm test -- --runInBand --runTestsByPath test/package-exports.test.ts",
|
|
51
74
|
"emsdk:install": "bash scripts/install-emsdk.sh",
|
|
52
75
|
"emsdk:env": "echo 'Run: source packages/emsdk/emsdk_env.sh'",
|
|
53
|
-
"test:wasi": "node --experimental-vm-modules node_modules/jest/bin/jest.js --runTestsByPath test/wasi.test.ts",
|
|
76
|
+
"test:wasi": "node --experimental-wasm-exnref --experimental-vm-modules node_modules/jest/bin/jest.js --runTestsByPath test/wasi.test.ts test/standalone-wasm-imports.test.ts",
|
|
77
|
+
"test:wasmedge": "node --experimental-wasm-exnref --experimental-vm-modules node_modules/jest/bin/jest.js --runTestsByPath test/wasmedge-standalone.test.ts test/wasmedge-runner.test.ts",
|
|
54
78
|
"test:cluster": "bash scripts/cluster-validation.sh",
|
|
55
|
-
"test:cluster:smoke": "bash scripts/cluster-validation.sh --duration=5 --stretch-duration=5 --readers=4 --stretch-readers=6"
|
|
79
|
+
"test:cluster:smoke": "bash scripts/cluster-validation.sh --duration=5 --stretch-duration=5 --readers=4 --stretch-readers=6",
|
|
80
|
+
"stress:sds:smoke": "bash scripts/stress-docker.sh smoke",
|
|
81
|
+
"stress:sds:docker-smoke": "bash scripts/stress-docker.sh docker-smoke",
|
|
82
|
+
"stress:sds:docker-fleet": "bash scripts/stress-docker.sh docker-fleet",
|
|
83
|
+
"stress:sds:full-config": "bash scripts/stress-docker.sh full-config",
|
|
84
|
+
"stress:sds:full": "bash scripts/stress-docker.sh full"
|
|
56
85
|
},
|
|
57
86
|
"repository": {
|
|
58
87
|
"type": "git",
|
|
@@ -84,6 +113,7 @@
|
|
|
84
113
|
"author": "Digital Arsenal <tj@digitalarsenal.io>",
|
|
85
114
|
"license": "Apache-2.0",
|
|
86
115
|
"dependencies": {
|
|
116
|
+
"flatbuffers": "^25.9.23",
|
|
87
117
|
"flatc-wasm": "^26.1.32",
|
|
88
118
|
"sql.js": "^1.10.0"
|
|
89
119
|
},
|
|
@@ -96,7 +126,7 @@
|
|
|
96
126
|
"vite": "^5.0.0"
|
|
97
127
|
},
|
|
98
128
|
"engines": {
|
|
99
|
-
"node": ">=
|
|
129
|
+
"node": ">=24.0.0"
|
|
100
130
|
},
|
|
101
131
|
"publishConfig": {
|
|
102
132
|
"access": "public"
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
7
|
+
|
|
8
|
+
COMMAND="smoke"
|
|
9
|
+
if [[ $# -gt 0 ]]; then
|
|
10
|
+
COMMAND="$1"
|
|
11
|
+
shift
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
RUN_ID="${RUN_ID:-sds-$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
15
|
+
SDS_SCHEMA_ROOT="${SDS_SCHEMA_ROOT:-$PROJECT_ROOT/../spacedatastandards.org/schema}"
|
|
16
|
+
if [[ -n "${OUTPUT_DIR:-}" ]]; then
|
|
17
|
+
OUTPUT_DIR_EXPLICIT=1
|
|
18
|
+
else
|
|
19
|
+
OUTPUT_DIR_EXPLICIT=0
|
|
20
|
+
OUTPUT_DIR="$PROJECT_ROOT/stress/results/$RUN_ID"
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
EXTRA_RUNNER_ARGS=()
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--schema-root)
|
|
27
|
+
SDS_SCHEMA_ROOT="$2"
|
|
28
|
+
shift 2
|
|
29
|
+
;;
|
|
30
|
+
--schema-root=*)
|
|
31
|
+
SDS_SCHEMA_ROOT="${1#*=}"
|
|
32
|
+
shift
|
|
33
|
+
;;
|
|
34
|
+
--output-dir)
|
|
35
|
+
OUTPUT_DIR="$2"
|
|
36
|
+
OUTPUT_DIR_EXPLICIT=1
|
|
37
|
+
shift 2
|
|
38
|
+
;;
|
|
39
|
+
--output-dir=*)
|
|
40
|
+
OUTPUT_DIR="${1#*=}"
|
|
41
|
+
OUTPUT_DIR_EXPLICIT=1
|
|
42
|
+
shift
|
|
43
|
+
;;
|
|
44
|
+
--nodes)
|
|
45
|
+
NODE_COUNT="$2"
|
|
46
|
+
shift 2
|
|
47
|
+
;;
|
|
48
|
+
--nodes=*)
|
|
49
|
+
NODE_COUNT="${1#*=}"
|
|
50
|
+
shift
|
|
51
|
+
;;
|
|
52
|
+
--node-id-offset)
|
|
53
|
+
NODE_ID_OFFSET="$2"
|
|
54
|
+
shift 2
|
|
55
|
+
;;
|
|
56
|
+
--node-id-offset=*)
|
|
57
|
+
NODE_ID_OFFSET="${1#*=}"
|
|
58
|
+
shift
|
|
59
|
+
;;
|
|
60
|
+
--storage-gb)
|
|
61
|
+
NODE_STORAGE_GB="$2"
|
|
62
|
+
shift 2
|
|
63
|
+
;;
|
|
64
|
+
--storage-gb=*)
|
|
65
|
+
NODE_STORAGE_GB="${1#*=}"
|
|
66
|
+
shift
|
|
67
|
+
;;
|
|
68
|
+
--records-per-node)
|
|
69
|
+
RECORDS_PER_NODE="$2"
|
|
70
|
+
shift 2
|
|
71
|
+
;;
|
|
72
|
+
--records-per-node=*)
|
|
73
|
+
RECORDS_PER_NODE="${1#*=}"
|
|
74
|
+
shift
|
|
75
|
+
;;
|
|
76
|
+
--batch-bytes)
|
|
77
|
+
BATCH_BYTES="$2"
|
|
78
|
+
shift 2
|
|
79
|
+
;;
|
|
80
|
+
--batch-bytes=*)
|
|
81
|
+
BATCH_BYTES="${1#*=}"
|
|
82
|
+
shift
|
|
83
|
+
;;
|
|
84
|
+
--query-concurrency)
|
|
85
|
+
QUERY_CONCURRENCY="$2"
|
|
86
|
+
shift 2
|
|
87
|
+
;;
|
|
88
|
+
--query-concurrency=*)
|
|
89
|
+
QUERY_CONCURRENCY="${1#*=}"
|
|
90
|
+
shift
|
|
91
|
+
;;
|
|
92
|
+
--hot-query-ratio)
|
|
93
|
+
HOT_QUERY_RATIO="$2"
|
|
94
|
+
shift 2
|
|
95
|
+
;;
|
|
96
|
+
--hot-query-ratio=*)
|
|
97
|
+
HOT_QUERY_RATIO="${1#*=}"
|
|
98
|
+
shift
|
|
99
|
+
;;
|
|
100
|
+
--runtime)
|
|
101
|
+
RUNTIME="$2"
|
|
102
|
+
shift 2
|
|
103
|
+
;;
|
|
104
|
+
--runtime=*)
|
|
105
|
+
RUNTIME="${1#*=}"
|
|
106
|
+
shift
|
|
107
|
+
;;
|
|
108
|
+
--node-isolation)
|
|
109
|
+
NODE_ISOLATION="$2"
|
|
110
|
+
shift 2
|
|
111
|
+
;;
|
|
112
|
+
--node-isolation=*)
|
|
113
|
+
NODE_ISOLATION="${1#*=}"
|
|
114
|
+
shift
|
|
115
|
+
;;
|
|
116
|
+
--run-id)
|
|
117
|
+
RUN_ID="$2"
|
|
118
|
+
shift 2
|
|
119
|
+
;;
|
|
120
|
+
--run-id=*)
|
|
121
|
+
RUN_ID="${1#*=}"
|
|
122
|
+
shift
|
|
123
|
+
;;
|
|
124
|
+
*)
|
|
125
|
+
EXTRA_RUNNER_ARGS+=("$1")
|
|
126
|
+
shift
|
|
127
|
+
;;
|
|
128
|
+
esac
|
|
129
|
+
done
|
|
130
|
+
if [[ "$OUTPUT_DIR_EXPLICIT" -eq 0 ]]; then
|
|
131
|
+
OUTPUT_DIR="$PROJECT_ROOT/stress/results/$RUN_ID"
|
|
132
|
+
fi
|
|
133
|
+
if [[ "${#EXTRA_RUNNER_ARGS[@]}" -gt 0 ]]; then
|
|
134
|
+
set -- "${EXTRA_RUNNER_ARGS[@]}"
|
|
135
|
+
else
|
|
136
|
+
set --
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
run_local_smoke() {
|
|
140
|
+
local runner_args=(
|
|
141
|
+
--mode "${STRESS_MODE:-smoke}"
|
|
142
|
+
--schema-root "$SDS_SCHEMA_ROOT"
|
|
143
|
+
--output-dir "$OUTPUT_DIR"
|
|
144
|
+
--nodes "${NODE_COUNT:-2}"
|
|
145
|
+
--storage-gb "${NODE_STORAGE_GB:-0.01}"
|
|
146
|
+
--records-per-node "${RECORDS_PER_NODE:-25}"
|
|
147
|
+
--run-id "$RUN_ID"
|
|
148
|
+
)
|
|
149
|
+
if [[ -n "${NODE_ID_OFFSET:-}" ]]; then runner_args+=(--node-id-offset "$NODE_ID_OFFSET"); fi
|
|
150
|
+
if [[ -n "${BATCH_BYTES:-}" ]]; then runner_args+=(--batch-bytes "$BATCH_BYTES"); fi
|
|
151
|
+
if [[ -n "${QUERY_CONCURRENCY:-}" ]]; then runner_args+=(--query-concurrency "$QUERY_CONCURRENCY"); fi
|
|
152
|
+
if [[ -n "${HOT_QUERY_RATIO:-}" ]]; then runner_args+=(--hot-query-ratio "$HOT_QUERY_RATIO"); fi
|
|
153
|
+
if [[ -n "${RUNTIME:-}" ]]; then runner_args+=(--runtime "$RUNTIME"); fi
|
|
154
|
+
if [[ -n "${NODE_ISOLATION:-}" ]]; then runner_args+=(--node-isolation "$NODE_ISOLATION"); fi
|
|
155
|
+
if [[ "$#" -gt 0 ]]; then runner_args+=("$@"); fi
|
|
156
|
+
|
|
157
|
+
npm run build
|
|
158
|
+
node "$PROJECT_ROOT/stress/sds/run.mjs" "${runner_args[@]}"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
run_docker() {
|
|
162
|
+
docker info >/dev/null
|
|
163
|
+
local schema_root_abs
|
|
164
|
+
schema_root_abs="$(cd "$SDS_SCHEMA_ROOT" && pwd)"
|
|
165
|
+
mkdir -p "$OUTPUT_DIR"
|
|
166
|
+
local output_dir_abs
|
|
167
|
+
output_dir_abs="$(cd "$OUTPUT_DIR" && pwd)"
|
|
168
|
+
SDS_SCHEMA_ROOT_HOST="$schema_root_abs" \
|
|
169
|
+
OUTPUT_DIR_HOST="$output_dir_abs" \
|
|
170
|
+
RUN_ID="$RUN_ID" \
|
|
171
|
+
STRESS_MODE="${STRESS_MODE:-smoke}" \
|
|
172
|
+
NODE_COUNT="${NODE_COUNT:-2}" \
|
|
173
|
+
NODE_STORAGE_GB="${NODE_STORAGE_GB:-0.01}" \
|
|
174
|
+
RECORDS_PER_NODE="${RECORDS_PER_NODE:-25}" \
|
|
175
|
+
BATCH_BYTES="${BATCH_BYTES:-1048576}" \
|
|
176
|
+
QUERY_CONCURRENCY="${QUERY_CONCURRENCY:-4}" \
|
|
177
|
+
HOT_QUERY_RATIO="${HOT_QUERY_RATIO:-0.9}" \
|
|
178
|
+
RUNTIME="${RUNTIME:-standalone}" \
|
|
179
|
+
NODE_ISOLATION="${NODE_ISOLATION:-logical}" \
|
|
180
|
+
docker compose -f "$PROJECT_ROOT/stress/docker/docker-compose.yml" up \
|
|
181
|
+
--build \
|
|
182
|
+
--abort-on-container-exit \
|
|
183
|
+
--exit-code-from controller \
|
|
184
|
+
controller
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
prepare_container_fleet_compose() {
|
|
188
|
+
npm run build
|
|
189
|
+
|
|
190
|
+
local schema_root_abs
|
|
191
|
+
schema_root_abs="$(cd "$SDS_SCHEMA_ROOT" && pwd)"
|
|
192
|
+
mkdir -p "$OUTPUT_DIR"
|
|
193
|
+
local output_dir_abs
|
|
194
|
+
output_dir_abs="$(cd "$OUTPUT_DIR" && pwd)"
|
|
195
|
+
FLEET_COMPOSE_FILE="$output_dir_abs/docker-compose.full.yml"
|
|
196
|
+
|
|
197
|
+
node "$PROJECT_ROOT/stress/sds/write-compose.mjs" \
|
|
198
|
+
--output-file "$FLEET_COMPOSE_FILE" \
|
|
199
|
+
--project-root "$PROJECT_ROOT" \
|
|
200
|
+
--schema-root-host "$schema_root_abs" \
|
|
201
|
+
--output-dir-host "$output_dir_abs" \
|
|
202
|
+
--run-id "$RUN_ID" \
|
|
203
|
+
--mode "${STRESS_MODE:-smoke}" \
|
|
204
|
+
--nodes "${NODE_COUNT:-2}" \
|
|
205
|
+
--storage-gb "${NODE_STORAGE_GB:-0.01}" \
|
|
206
|
+
--records-per-node "${RECORDS_PER_NODE:-25}" \
|
|
207
|
+
--batch-bytes "${BATCH_BYTES:-1048576}" \
|
|
208
|
+
--query-concurrency "${QUERY_CONCURRENCY:-4}" \
|
|
209
|
+
--hot-query-ratio "${HOT_QUERY_RATIO:-0.9}" \
|
|
210
|
+
--runtime "${RUNTIME:-standalone}"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
run_container_fleet() {
|
|
214
|
+
prepare_container_fleet_compose
|
|
215
|
+
docker info >/dev/null
|
|
216
|
+
|
|
217
|
+
local node_count="${NODE_COUNT:-2}"
|
|
218
|
+
local worker_services=()
|
|
219
|
+
local node_id
|
|
220
|
+
for ((node_id = 0; node_id < node_count; node_id++)); do
|
|
221
|
+
worker_services+=("worker-$node_id")
|
|
222
|
+
done
|
|
223
|
+
|
|
224
|
+
docker compose -f "$FLEET_COMPOSE_FILE" up --build "${worker_services[@]}"
|
|
225
|
+
docker compose -f "$FLEET_COMPOSE_FILE" build aggregator
|
|
226
|
+
docker compose -f "$FLEET_COMPOSE_FILE" run --no-deps --rm aggregator
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
run_full() {
|
|
230
|
+
if [[ "${CONFIRM_FULL_STRESS:-}" != "1" ]]; then
|
|
231
|
+
echo "Full stress requires CONFIRM_FULL_STRESS=1 because it targets 100 nodes and 1 GB/node." >&2
|
|
232
|
+
exit 2
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
local parent
|
|
236
|
+
parent="$(dirname "$OUTPUT_DIR")"
|
|
237
|
+
mkdir -p "$parent"
|
|
238
|
+
local available_kb
|
|
239
|
+
available_kb="$(df -Pk "$parent" | awk 'NR == 2 { print $4 }')"
|
|
240
|
+
local required_kb=$((110 * 1024 * 1024))
|
|
241
|
+
if [[ "$available_kb" -lt "$required_kb" ]]; then
|
|
242
|
+
echo "Full stress requires at least 110 GB free near $parent; available KB: $available_kb." >&2
|
|
243
|
+
exit 3
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
RECORDS_PER_NODE="${RECORDS_PER_NODE:-20000}"
|
|
247
|
+
QUERY_CONCURRENCY="${QUERY_CONCURRENCY:-64}"
|
|
248
|
+
HOT_QUERY_RATIO="${HOT_QUERY_RATIO:-0.01}"
|
|
249
|
+
STRESS_MODE=full NODE_COUNT=100 NODE_STORAGE_GB=1 NODE_ISOLATION=container run_container_fleet
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
case "$COMMAND" in
|
|
253
|
+
smoke)
|
|
254
|
+
run_local_smoke "$@"
|
|
255
|
+
;;
|
|
256
|
+
docker-smoke)
|
|
257
|
+
run_docker "$@"
|
|
258
|
+
;;
|
|
259
|
+
docker-fleet)
|
|
260
|
+
STRESS_MODE="${STRESS_MODE:-smoke}" NODE_ISOLATION=container run_container_fleet "$@"
|
|
261
|
+
;;
|
|
262
|
+
full-config)
|
|
263
|
+
RECORDS_PER_NODE="${RECORDS_PER_NODE:-20000}" \
|
|
264
|
+
QUERY_CONCURRENCY="${QUERY_CONCURRENCY:-64}" \
|
|
265
|
+
HOT_QUERY_RATIO="${HOT_QUERY_RATIO:-0.01}" \
|
|
266
|
+
STRESS_MODE=full \
|
|
267
|
+
NODE_COUNT="${NODE_COUNT:-100}" \
|
|
268
|
+
NODE_STORAGE_GB="${NODE_STORAGE_GB:-1}" \
|
|
269
|
+
NODE_ISOLATION=container \
|
|
270
|
+
prepare_container_fleet_compose
|
|
271
|
+
;;
|
|
272
|
+
full)
|
|
273
|
+
run_full "$@"
|
|
274
|
+
;;
|
|
275
|
+
*)
|
|
276
|
+
echo "Usage: scripts/stress-docker.sh [smoke|docker-smoke|docker-fleet|full-config|full] [runner args]" >&2
|
|
277
|
+
exit 2
|
|
278
|
+
;;
|
|
279
|
+
esac
|
package/sdm/flatsql-spatial.wasm
CHANGED
|
Binary file
|