perf: cache local tsgo checks

This commit is contained in:
Peter Steinberger
2026-04-10 17:06:05 +01:00
parent aaf38acc07
commit be9bef32df
3 changed files with 80 additions and 3 deletions

View File

@@ -6,6 +6,7 @@ import path from "node:path";
const GIB = 1024 ** 3;
const DEFAULT_LOCAL_GO_GC = "30";
const DEFAULT_LOCAL_GO_MEMORY_LIMIT = "3GiB";
const DEFAULT_LOCAL_TSGO_BUILD_INFO_FILE = ".artifacts/tsgo-cache/root.tsbuildinfo";
const DEFAULT_LOCK_TIMEOUT_MS = 10 * 60 * 1000;
const DEFAULT_LOCK_POLL_MS = 500;
const DEFAULT_LOCK_PROGRESS_MS = 15 * 1000;
@@ -26,6 +27,7 @@ export function hasFlag(args, name) {
export function applyLocalTsgoPolicy(args, env, hostResources) {
const nextEnv = { ...env };
const nextArgs = [...args];
const defaultProjectRun = nextArgs.length === 0;
if (!hasFlag(nextArgs, "--declaration") && !nextArgs.includes("-d")) {
insertBeforeSeparator(nextArgs, "--declaration", "false");
@@ -35,6 +37,15 @@ export function applyLocalTsgoPolicy(args, env, hostResources) {
return { env: nextEnv, args: nextArgs };
}
if (defaultProjectRun) {
insertBeforeSeparator(nextArgs, "--incremental");
insertBeforeSeparator(
nextArgs,
"--tsBuildInfoFile",
nextEnv.OPENCLAW_TSGO_BUILD_INFO_FILE ?? DEFAULT_LOCAL_TSGO_BUILD_INFO_FILE,
);
}
if (shouldThrottleLocalHeavyChecks(nextEnv, hostResources)) {
insertBeforeSeparator(nextArgs, "--singleThreaded");
insertBeforeSeparator(nextArgs, "--checkers", "1");

View File

@@ -1,4 +1,5 @@
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import {
acquireLocalHeavyCheckLockSync,
@@ -8,6 +9,10 @@ import {
const { args: finalArgs, env } = applyLocalTsgoPolicy(process.argv.slice(2), process.env);
const tsgoPath = path.resolve("node_modules", ".bin", "tsgo");
const tsBuildInfoFile = readFlagValue(finalArgs, "--tsBuildInfoFile");
if (tsBuildInfoFile) {
fs.mkdirSync(path.dirname(path.resolve(tsBuildInfoFile)), { recursive: true });
}
const releaseLock = acquireLocalHeavyCheckLockSync({
cwd: process.cwd(),
env,
@@ -29,3 +34,16 @@ try {
} finally {
releaseLock();
}
function readFlagValue(args, name) {
for (let index = 0; index < args.length; index++) {
const arg = args[index];
if (arg === name) {
return args[index + 1];
}
if (arg.startsWith(`${name}=`)) {
return arg.slice(name.length + 1);
}
}
return undefined;
}

View File

@@ -31,7 +31,16 @@ describe("local-heavy-check-runtime", () => {
it("tightens local tsgo runs on constrained hosts", () => {
const { args, env } = applyLocalTsgoPolicy([], makeEnv(), CONSTRAINED_HOST);
expect(args).toEqual(["--declaration", "false", "--singleThreaded", "--checkers", "1"]);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
"--singleThreaded",
"--checkers",
"1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});
@@ -77,11 +86,41 @@ describe("local-heavy-check-runtime", () => {
it("keeps local tsgo at full speed on roomy hosts in auto mode", () => {
const { args, env } = applyLocalTsgoPolicy([], makeEnv(), ROOMY_HOST);
expect(args).toEqual(["--declaration", "false"]);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
]);
expect(env.GOGC).toBeUndefined();
expect(env.GOMEMLIMIT).toBeUndefined();
});
it("uses the configured local tsgo build info file", () => {
const { args } = applyLocalTsgoPolicy(
[],
makeEnv({
OPENCLAW_TSGO_BUILD_INFO_FILE: ".artifacts/custom/tsgo.tsbuildinfo",
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/custom/tsgo.tsbuildinfo",
]);
});
it("avoids incremental cache reuse for ad hoc tsgo runs", () => {
const { args } = applyLocalTsgoPolicy(["--extendedDiagnostics"], makeEnv(), ROOMY_HOST);
expect(args).toEqual(["--extendedDiagnostics", "--declaration", "false"]);
});
it("allows forcing the throttled tsgo policy on roomy hosts", () => {
const { args, env } = applyLocalTsgoPolicy(
[],
@@ -91,7 +130,16 @@ describe("local-heavy-check-runtime", () => {
ROOMY_HOST,
);
expect(args).toEqual(["--declaration", "false", "--singleThreaded", "--checkers", "1"]);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
"--singleThreaded",
"--checkers",
"1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});