Files
paseo/packages/server/scripts/measure-file-observer.test.ts
T
Mohamed Boudra 48a1497fc0 Load the Changes diff quickly while the daemon reconciles worktrees (#9243)
* fix(server): keep cold diffs out from behind background git fan-out

Add a background lane to the git process scheduler and run reconciliation
checkout reads, observation-driven workspace refreshes and background fetches
in it. Bound reconciliation checkout reads to four at a time. Stop the Linux
file observer's startup scan from reporting existing files as creates, which
made every cold diff compute and discard its first revision.

* fix(server): pick the git job when its start token fires

Background jobs that already reserved a start-rate token no longer start
ahead of normal work submitted after them.

* fix(server): re-read the working tree once its watcher covers it

The Linux observer no longer reports pre-existing files at startup, so an
edit made between a workspace's first snapshot and its watcher subscribing
reached no consumer. WorkspaceGit now runs one background working-tree read
once observation setup completes with a live watcher.

Demand refreshes keep the caller's Git lane instead of forcing normal, so
user actions running at high priority are not demoted.

Scope the populated-tree observer test to Linux (FSEvents replays recent
writes) and update the observer benchmark test, which expected the removed
startup batch.

* fix(server): re-read checkout metadata once observation covers it

A branch switch made before the Git metadata watcher subscribed left the
cached branch stale. The post-coverage read now refreshes structure as well
as the working tree, matching the refresh the Linux startup events used to
trigger.
2026-11-10 10:21:13 +07:00

60 lines
2.3 KiB
TypeScript

import { execFile } from "node:child_process";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { promisify } from "node:util";
import { expect, test } from "vitest";
const execFileAsync = promisify(execFile);
// The Linux backend scans the existing inventory at startup without reporting
// it. Other backends have different startup semantics.
test.skipIf(process.platform !== "linux").each(["healthy", "directory-churn"])(
"%s benchmark over a large pre-populated tree reports only later edits",
async (mode) => {
const temporaryRoot = await mkdtemp(join(tmpdir(), "paseo-watch-benchmark-test-"));
try {
const { stdout } = await execFileAsync(
process.execPath,
[
// Lower the argument limit instead of creating hundreds of thousands
// of files. This still runs the real observer and benchmark CLI.
"--stack-size=256",
"--import",
"tsx",
fileURLToPath(new URL("./measure-file-observer.ts", import.meta.url)),
"--child",
],
{
timeout: 60_000,
env: {
...process.env,
TMPDIR: temporaryRoot,
PASEO_WATCH_BENCH_MODE: mode,
PASEO_WATCH_BENCH_ROOTS: "1",
PASEO_WATCH_BENCH_DIRS: "10",
PASEO_WATCH_BENCH_PREEXISTING_FILES: "40000",
PASEO_WATCH_BENCH_IGNORED_FILES: "1",
PASEO_WATCH_BENCH_EDITS: "1",
PASEO_WATCH_BENCH_SUSTAINED_EDITS: "1",
PASEO_WATCH_BENCH_SUSTAINED_INTERVAL_MS: "1",
PASEO_WATCH_BENCH_CHURN_DIRECTORIES: "10",
PASEO_WATCH_BENCH_CHURN_FILES_PER_DIRECTORY: "4000",
PASEO_WATCH_BENCH_CHURN_ROUNDS: "1",
PASEO_WATCH_BENCH_CHURN_DIRECTORIES_PER_ROUND: "2",
},
},
);
const measurement = JSON.parse(stdout);
expect(measurement.startupEvents).toBe(0);
expect(measurement.deliveredEvents).toBeGreaterThan(measurement.startupEvents);
expect(measurement.missedTrackedPaths).toBe(0);
expect(measurement.ignoredEvents).toBe(0);
} finally {
await rm(temporaryRoot, { recursive: true, force: true });
}
},
90_000,
);