mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
* perf(store): add best-effort V8 sidecars beside canonical JSON caches Warm ParsedFile and parse-cache loads skip JSON.parse when a sidecar is present. JSON remains authoritative: envelope validation plus v8.deserialize decide the hit, and any failure falls back without reparsing. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(store): require generation bind or sidecar drop before cache overwrite A same-length JSON rewrite could accept a leftover V8 sidecar if both generation rotation and unlink failed. Refuse the new generation unless at least one of those invalidations succeeds; skip publishing a sidecar when only the drop succeeded. detect_changes --scope all: 7 files, risk low, no affected processes. tsc --noEmit clean; 115/115 relevant unit tests; cache-related integration tests pass. parse-impl-env-reads worker-ready timeout is pre-existing (same 5 failures with this change set stashed). ESLint 0 errors; remaining warnings are pre-existing and not on changed lines. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(autofix): apply prettier + eslint fixes via /autofix command * refactor(store): share V8 overwrite invalidation across persist paths The bind-or-drop gate lived in five writers. One helper keeps the protocol in a single place and lets bind/drop run together on the async path. detect_changes --scope all: 3 files, risk low, no affected processes. Co-authored-by: Cursor <cursoragent@cursor.com> * perf(store): hardlink durable ParsedFile shards into the run store Warm restore of parsedfile-cache into parsedfile-store now publishes all four shard files via fs.link, falling back to copy-into-tmp + rename so a leftover dest hardlink can never be written through. JSON remains the canonical cache; V8 sidecars ride the same path. Co-authored-by: Cursor <cursoragent@cursor.com> * perf(store): load immutable V8 shards in place, drop JSON fallback Warm analyze was still paying JSON.parse plus a restore copy. One .v8 envelope per shard and SCHEMA_BUMP 81 make a miss re-extract instead of serving a stale JSON twin. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(store): validate durable V8 warm-cache restores Reject incomplete or corrupt durable generations and snapshot valid shards before skipping parse workers, preserving ParsedFiles when persistence fails. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(store): drop unused durable load path Load ParsedFiles only from the run-store snapshot and share one checksummed payload reader so inspect and deserialize stay consistent. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
91 lines
3 KiB
JavaScript
91 lines
3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Optional V8 sidecar warm-load bench (#3089).
|
|
*
|
|
* Not part of `npm test`. Measures repeated warm loads of the `.v8` ParsedFile
|
|
* shards already on disk through the production loader. Replay of identical
|
|
* shards is throughput-only — it is not unique-object scale.
|
|
*
|
|
* Copies the store into a temporary workspace first. The source cache is
|
|
* never mutated.
|
|
*
|
|
* Usage (from gitnexus/):
|
|
* node --expose-gc --import tsx bench/v8-sidecar/measure.mjs <storagePath>
|
|
*/
|
|
import { cp, mkdtemp, readdir, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import path from 'node:path';
|
|
import { performance } from 'node:perf_hooks';
|
|
import { loadParsedFilesForPaths } from '../../src/storage/parsedfile-store.ts';
|
|
import { inspectV8Cache } from '../../src/storage/v8-sidecar.ts';
|
|
|
|
const srcStorage = process.argv[2];
|
|
if (!srcStorage) {
|
|
console.error('usage: node --expose-gc --import tsx bench/v8-sidecar/measure.mjs <storagePath>');
|
|
process.exit(2);
|
|
}
|
|
|
|
const srcStoreDir = path.join(srcStorage, 'parsedfile-store');
|
|
const benchRoot = await mkdtemp(path.join(tmpdir(), 'gnx-v8-bench-'));
|
|
const storeDir = path.join(benchRoot, 'parsedfile-store');
|
|
const PATH_SOURCE_SHARDS = 8;
|
|
const RUNS = 3;
|
|
|
|
try {
|
|
await cp(srcStoreDir, storeDir, { recursive: true });
|
|
|
|
const names = (await readdir(storeDir))
|
|
.filter((f) => f.endsWith('.v8') && !f.includes('.v8.'))
|
|
.sort();
|
|
if (names.length === 0) {
|
|
throw new Error(
|
|
`no .v8 ParsedFile shards in ${srcStoreDir} — run an analyze that populates the store first`,
|
|
);
|
|
}
|
|
|
|
const want = new Set();
|
|
let sourceShards = 0;
|
|
for (const name of names) {
|
|
const inspected = await inspectV8Cache(path.join(storeDir, name));
|
|
if (!inspected) continue;
|
|
sourceShards++;
|
|
for (const filePath of inspected.paths) want.add(filePath);
|
|
if (sourceShards >= PATH_SOURCE_SHARDS) break;
|
|
}
|
|
if (want.size === 0) {
|
|
throw new Error(
|
|
`no file paths readable from ${names.length} shard(s) in ${srcStoreDir} — shards may be from another Node/V8 runtime, so re-analyze with this runtime`,
|
|
);
|
|
}
|
|
|
|
const rss = () => Math.round(process.memoryUsage().rss / 1024 / 1024);
|
|
const heap = () => Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
|
|
const run = async (label) => {
|
|
if (typeof globalThis.gc === 'function') globalThis.gc();
|
|
const t0 = performance.now();
|
|
const loaded = await loadParsedFilesForPaths(benchRoot, want);
|
|
const ms = Math.round(performance.now() - t0);
|
|
if (loaded.size !== want.size) {
|
|
throw new Error(`incomplete V8 load: requested ${want.size} paths but loaded ${loaded.size}`);
|
|
}
|
|
if (typeof globalThis.gc === 'function') globalThis.gc();
|
|
console.log(
|
|
JSON.stringify({
|
|
label,
|
|
shards: names.length,
|
|
wantPaths: want.size,
|
|
files: loaded.size,
|
|
ms,
|
|
rssMiB: rss(),
|
|
heapUsedMiB: heap(),
|
|
}),
|
|
);
|
|
};
|
|
|
|
for (let i = 1; i <= RUNS; i++) {
|
|
await run(`v8-load-${i}`);
|
|
}
|
|
} finally {
|
|
await rm(benchRoot, { recursive: true, force: true });
|
|
}
|