mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-25 10:42:45 +00:00
fix(server): let Git observation measurements reach their summary
Startup discovery queues a refresh beyond the old 250 ms wait. Wait for Git command quiescence at phase boundaries so idle measurements exclude startup work, and pass the observer to healthy teardown before measuring degraded polling.
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
import {
|
||||
startGitCommandMetrics,
|
||||
stopGitCommandMetrics,
|
||||
waitForGitCommandMetricsIdle,
|
||||
type GitCommandMetricsSnapshot,
|
||||
} from "../src/utils/run-git-command.js";
|
||||
import { CheckoutDiffManager } from "../src/server/checkout-diff-manager.js";
|
||||
@@ -160,6 +161,7 @@ async function measurePhase(input: {
|
||||
serviceMetrics.workspaceRefreshQueuedCount === 0
|
||||
);
|
||||
}, "observation queue to drain");
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
} finally {
|
||||
metrics = stopGitCommandMetrics();
|
||||
}
|
||||
@@ -243,7 +245,9 @@ async function main(): Promise<void> {
|
||||
healthy.watcher.subscriptions.size === 2,
|
||||
"healthy bootstrap",
|
||||
);
|
||||
await sleep(250);
|
||||
// Linux startup discovery schedules a one-second debounced refresh even
|
||||
// after subscriptions are ready. Keep that work in the bootstrap phase.
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
const bootstrapMetrics = stopGitCommandMetrics();
|
||||
const bootstrapServiceMetrics = healthy.service.getMetrics();
|
||||
phases.bootstrap = {
|
||||
@@ -342,6 +346,7 @@ async function main(): Promise<void> {
|
||||
diffManager = null;
|
||||
await closeMeasuredService({
|
||||
service: healthy.service,
|
||||
observer: healthy.watcher.observer,
|
||||
subscriptions: healthy.watcher.subscriptions,
|
||||
});
|
||||
healthy = null;
|
||||
@@ -357,7 +362,9 @@ async function main(): Promise<void> {
|
||||
degraded.service.getMetrics().workspaceObservationSetupInFlightCount === 0,
|
||||
"degraded bootstrap",
|
||||
);
|
||||
await sleep(250);
|
||||
// Linux startup discovery schedules a one-second debounced refresh even
|
||||
// after subscriptions are ready. Keep that work in the bootstrap phase.
|
||||
await waitForGitCommandMetricsIdle({ quietMs: 1_500, timeoutMs: 8_000 });
|
||||
const degradedBootstrapMetrics = stopGitCommandMetrics();
|
||||
const degradedBootstrapServiceMetrics = degraded.service.getMetrics();
|
||||
phases.degradedBootstrap = {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { execFile, execFileSync } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import pino from "pino";
|
||||
@@ -522,3 +524,37 @@ test("a late Git-ignored tree is pruned while tracked changes still notify consu
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}, 15_000);
|
||||
|
||||
test("Git observation measurement separates startup from idle and reaches its degraded summary", async () => {
|
||||
const script = fileURLToPath(
|
||||
new URL("../../scripts/measure-git-observation.ts", import.meta.url),
|
||||
);
|
||||
const { stdout } = await promisify(execFile)(process.execPath, ["--import", "tsx", script], {
|
||||
timeout: 30_000,
|
||||
maxBuffer: 1024 * 1024,
|
||||
});
|
||||
const summary = stdout
|
||||
.split("\n")
|
||||
.find((line) => line.startsWith("GIT_OBSERVATION_MEASUREMENT "));
|
||||
expect(summary).toBeTypeOf("string");
|
||||
const report = JSON.parse(summary!.slice("GIT_OBSERVATION_MEASUREMENT ".length));
|
||||
expect(Object.keys(report.phases)).toEqual([
|
||||
"bootstrap",
|
||||
"legacyFullRefreshReference",
|
||||
"idle",
|
||||
"activeDiff",
|
||||
"editBurst",
|
||||
"ignoredStorm",
|
||||
"degradedBootstrap",
|
||||
"degradedWatcher",
|
||||
]);
|
||||
expect(report.phases.idle.gitCommands).toBe(0);
|
||||
expect(report.phases.ignoredStorm.gitCommands).toBe(0);
|
||||
expect(report.phases.bootstrap.producers.structural).toBeGreaterThanOrEqual(1);
|
||||
expect(report.phases.activeDiff.producers.worktree).toBeGreaterThanOrEqual(1);
|
||||
expect(report.phases.editBurst.producers.worktree).toBeLessThanOrEqual(2);
|
||||
expect(report.phases.degradedWatcher.producers.worktree).toBeGreaterThanOrEqual(1);
|
||||
for (const phase of Object.values(report.phases) as Array<{ queueAfter: unknown }>) {
|
||||
expect(phase.queueAfter).toEqual({ inFlight: 0, queued: 0 });
|
||||
}
|
||||
}, 35_000);
|
||||
|
||||
Reference in New Issue
Block a user