authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-10-05 17:40:32-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-05 17:40:32-07:00
logdcbaf05279984187b96c99edc2416abf91e77b96
treec9d9190c18e27626098bdb9317927123e3f51932
parent1024941575067f68d909c6b98f56b02edac25b37
signature Signed by PGP key B5690EEEBB952194

perf(server): idle status polls and PR sweeps start fewer git processes (#16272)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

4 files changed, 248 insertions(+), 87 deletions(-)

apps/server/src/git/GitManager.test.ts+43
...@@ -1071,6 +1071,49 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => {...@@ -1071,6 +1071,49 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => {
1071 }),1071 }),
1072 );1072 );
10731073
1074 it.effect("a branch tracking origin reads origin's URL once per PR lookup", () =>
1075 Effect.gen(function* () {
1076 const repoDir = yield* makeTempDir("t3code-git-manager-");
1077 yield* initRepo(repoDir);
1078 const remoteDir = yield* createBareRemote();
1079 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1080 yield* runGit(repoDir, ["checkout", "-b", "feature/origin-once"]);
1081 yield* runGit(repoDir, ["push", "-u", "origin", "feature/origin-once"]);
1082
1083 const gitConfigReads: string[] = [];
1084 const { manager } = yield* makeManager({
1085 gitConfigReads,
1086 ghScenario: {
1087 prListSequence: [
1088 // Fake gh returns raw JSON stdout, matching the CLI boundary under test.
1089 // @effect-diagnostics-next-line preferSchemaOverJson:off
1090 JSON.stringify([
1091 {
1092 number: 217,
1093 title: "Origin once PR",
1094 url: "https://github.com/pingdotgg/t3code/pull/217",
1095 baseRefName: "main",
1096 headRefName: "feature/origin-once",
1097 state: "OPEN",
1098 updatedAt: "2026-04-03T15:00:00Z",
1099 },
1100 ]),
1101 ],
1102 },
1103 });
1104
1105 yield* manager.branchPullRequest({ cwd: repoDir, branch: "feature/origin-once" });
1106 gitConfigReads.length = 0;
1107 const pullRequest = yield* manager.branchPullRequest({
1108 cwd: repoDir,
1109 branch: "feature/origin-once",
1110 });
1111
1112 expect(pullRequest?.number).toBe(217);
1113 expect(gitConfigReads.filter((key) => key === "remote.origin.url")).toHaveLength(1);
1114 }),
1115 );
1116
1074 it.effect("turn-end refresh finds a new PR and keeps known PRs cached", () =>1117 it.effect("turn-end refresh finds a new PR and keeps known PRs cached", () =>
1075 Effect.gen(function* () {1118 Effect.gen(function* () {
1076 const repoDir = yield* makeTempDir("t3code-git-manager-");1119 const repoDir = yield* makeTempDir("t3code-git-manager-");
apps/server/src/git/GitManager.ts+18-13
...@@ -1404,17 +1404,25 @@ export const make = Effect.gen(function* () {...@@ -1404,17 +1404,25 @@ export const make = Effect.gen(function* () {
1404 };1404 };
1405 });1405 });
14061406
1407 // Returns [head remote, origin]. Most branches track origin, so read it once.
1408 const resolveHeadAndOriginContexts = (cwd: string, remoteName: string | null) =>
1409 remoteName === "origin"
1410 ? resolveRemoteRepositoryContext(cwd, "origin").pipe(
1411 Effect.map((origin) => [origin, origin] as const),
1412 )
1413 : Effect.all(
1414 [
1415 resolveRemoteRepositoryContext(cwd, remoteName),
1416 resolveRemoteRepositoryContext(cwd, "origin"),
1417 ],
1418 { concurrency: "unbounded" },
1419 );
1420
1407 const resolvePrLookupRepositoryIdentity = Effect.fn("resolvePrLookupRepositoryIdentity")(1421 const resolvePrLookupRepositoryIdentity = Effect.fn("resolvePrLookupRepositoryIdentity")(
1408 function* (cwd: string, branch: string, remoteNameOverride?: string) {1422 function* (cwd: string, branch: string, remoteNameOverride?: string) {
1409 const remoteName =1423 const remoteName =
1410 remoteNameOverride ?? (yield* readConfigValueNullable(cwd, `branch.${branch}.remote`));1424 remoteNameOverride ?? (yield* readConfigValueNullable(cwd, `branch.${branch}.remote`));
1411 const [headRemote, targetRemote] = yield* Effect.all(1425 const [headRemote, targetRemote] = yield* resolveHeadAndOriginContexts(cwd, remoteName);
1412 [
1413 resolveRemoteRepositoryContext(cwd, remoteName),
1414 resolveRemoteRepositoryContext(cwd, "origin"),
1415 ],
1416 { concurrency: "unbounded" },
1417 );
1418 return {1426 return {
1419 remoteName,1427 remoteName,
1420 headRemoteUrlKey:1428 headRemoteUrlKey:
...@@ -1438,12 +1446,9 @@ export const make = Effect.gen(function* () {...@@ -1438,12 +1446,9 @@ export const make = Effect.gen(function* () {
1438 const shouldProbeLocalBranchSelector =1446 const shouldProbeLocalBranchSelector =
1439 headBranchFromUpstream.length === 0 || headBranch === details.branch;1447 headBranchFromUpstream.length === 0 || headBranch === details.branch;
14401448
1441 const [remoteRepository, originRepository] = yield* Effect.all(1449 const [remoteRepository, originRepository] = yield* resolveHeadAndOriginContexts(
1442 [1450 cwd,
1443 resolveRemoteRepositoryContext(cwd, remoteName),1451 remoteName,
1444 resolveRemoteRepositoryContext(cwd, "origin"),
1445 ],
1446 { concurrency: "unbounded" },
1447 );1452 );
14481453
1449 const isCrossRepository =1454 const isCrossRepository =
apps/server/src/vcs/VcsDriverRegistry.test.ts+126-70
...@@ -1,7 +1,9 @@...@@ -1,7 +1,9 @@
1import { assert, it, describe } from "@effect/vitest";1import { assert, it, describe } from "@effect/vitest";
2import * as NodeServices from "@effect/platform-node/NodeServices";2import * as NodeServices from "@effect/platform-node/NodeServices";
3import * as Effect from "effect/Effect";3import * as Effect from "effect/Effect";
4import * as FileSystem from "effect/FileSystem";
4import * as Layer from "effect/Layer";5import * as Layer from "effect/Layer";
6import * as Path from "effect/Path";
5import { ChildProcessSpawner } from "effect/process";7import { ChildProcessSpawner } from "effect/process";
68
7import * as VcsProcess from "./VcsProcess.ts";9import * as VcsProcess from "./VcsProcess.ts";
...@@ -43,9 +45,10 @@ describe("VcsDriverRegistry", () => {...@@ -43,9 +45,10 @@ describe("VcsDriverRegistry", () => {
43 }).pipe(Effect.provide(layer));45 }).pipe(Effect.provide(layer));
44 });46 });
4547
46 it.effect("caches repository detection for repeated resolves in the same cwd and kind", () => {48 // Answers detection like git: the nearest folder at or above the cwd, up to
47 const calls: VcsProcess.VcsProcessInput[] = [];49 // `rootDir`, that holds `.git` is the repository.
48 const layer = Layer.effect(VcsDriverRegistry.VcsDriverRegistry, VcsDriverRegistry.make).pipe(50 const makeDiskBackedLayer = (rootDir: string, calls: string[]) =>
51 Layer.effect(VcsDriverRegistry.VcsDriverRegistry, VcsDriverRegistry.make).pipe(
49 Layer.provide(NodeServices.layer),52 Layer.provide(NodeServices.layer),
50 Layer.provide(53 Layer.provide(
51 Layer.mock(VcsProjectConfig.VcsProjectConfig)({54 Layer.mock(VcsProjectConfig.VcsProjectConfig)({
...@@ -55,86 +58,139 @@ describe("VcsDriverRegistry", () => {...@@ -55,86 +58,139 @@ describe("VcsDriverRegistry", () => {
55 Layer.provide(58 Layer.provide(
56 Layer.mock(VcsProcess.VcsProcess)({59 Layer.mock(VcsProcess.VcsProcess)({
57 run: (input) =>60 run: (input) =>
58 Effect.sync(() => {61 Effect.gen(function* () {
59 calls.push(input);62 const fs = yield* FileSystem.FileSystem;
60 const normalizedArgs =63 const path = yield* Path.Path;
61 input.args[0] === "-C" && input.args.length >= 2 ? input.args.slice(2) : input.args;64 const command = normalizeGitArgs(input.args).join(" ");
62 const command = normalizedArgs.join(" ");65 calls.push(command);
63 if (command === "rev-parse --is-inside-work-tree") {66 let repoDir: string | null = input.cwd;
64 return processOutput("true\n");67 while (repoDir !== null && !(yield* fs.exists(path.join(repoDir, ".git")))) {
68 repoDir = repoDir === rootDir ? null : path.dirname(repoDir);
65 }69 }
66 if (command === "rev-parse --show-toplevel") {70 if (repoDir === null) {
67 return processOutput("/repo\n");71 return {
72 ...processOutput(""),
73 exitCode: ChildProcessSpawner.ExitCode(128),
74 stderr: "fatal: not a git repository",
75 };
68 }76 }
77 if (command === "rev-parse --is-inside-work-tree") return processOutput("true\n");
78 if (command === "rev-parse --show-toplevel") return processOutput(`${repoDir}\n`);
69 if (command === "rev-parse --git-common-dir") {79 if (command === "rev-parse --git-common-dir") {
70 return processOutput("/repo/.git\n");80 return processOutput(`${path.relative(input.cwd, path.join(repoDir, ".git"))}\n`);
71 }81 }
72 return processOutput("");82 return processOutput("");
73 }),83 }).pipe(Effect.provide(NodeServices.layer), Effect.orDie),
74 }),84 }),
75 ),85 ),
76 );86 );
7787
78 return Effect.gen(function* () {88 it.effect("caches repository detection for repeated resolves in the same cwd and kind", () =>
79 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;89 Effect.gen(function* () {
80 const first = yield* registry.resolve({ cwd: "/repo", requestedKind: "git" });90 const fs = yield* FileSystem.FileSystem;
81 const second = yield* registry.resolve({ cwd: "/repo", requestedKind: "git" });91 const path = yield* Path.Path;
8292 const repoDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-vcs-registry-" });
83 assert.equal(first.repository.rootPath, "/repo");93 yield* fs.makeDirectory(path.join(repoDir, ".git"));
84 assert.equal(second.repository.rootPath, "/repo");94 const calls: string[] = [];
85 assert.deepStrictEqual(95
86 calls.map((call) => normalizeGitArgs(call.args).join(" ")),96 yield* Effect.gen(function* () {
87 [97 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;
98 const first = yield* registry.resolve({ cwd: repoDir, requestedKind: "git" });
99 const second = yield* registry.resolve({ cwd: repoDir, requestedKind: "git" });
100
101 assert.equal(first.repository.rootPath, repoDir);
102 assert.equal(second.repository.rootPath, repoDir);
103 assert.deepStrictEqual(calls, [
88 "rev-parse --is-inside-work-tree",104 "rev-parse --is-inside-work-tree",
89 "rev-parse --show-toplevel",105 "rev-parse --show-toplevel",
90 "rev-parse --git-common-dir",106 "rev-parse --git-common-dir",
91 ],107 ]);
92 );108 }).pipe(Effect.provide(makeDiskBackedLayer(repoDir, calls)));
93 }).pipe(Effect.provide(layer));109 }).pipe(Effect.provide(NodeServices.layer)),
94 });110 );
95111
96 it.effect("detects a repository created after a negative lookup", () => {112 it.effect("detects again when a cached repository is removed from disk", () =>
97 let insideWorkTreeChecks = 0;113 Effect.gen(function* () {
98 const layer = Layer.effect(VcsDriverRegistry.VcsDriverRegistry, VcsDriverRegistry.make).pipe(114 const fs = yield* FileSystem.FileSystem;
99 Layer.provide(NodeServices.layer),115 const path = yield* Path.Path;
100 Layer.provide(116 const repoDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-vcs-registry-" });
101 Layer.mock(VcsProjectConfig.VcsProjectConfig)({117 yield* fs.makeDirectory(path.join(repoDir, ".git"));
102 resolveKind: (input) => Effect.succeed(input.requestedKind ?? "auto"),118 const calls: string[] = [];
103 }),
104 ),
105 Layer.provide(
106 Layer.mock(VcsProcess.VcsProcess)({
107 run: (input) =>
108 Effect.sync(() => {
109 const command = normalizeGitArgs(input.args).join(" ");
110 if (command === "rev-parse --is-inside-work-tree") {
111 insideWorkTreeChecks += 1;
112 return insideWorkTreeChecks === 1
113 ? {
114 ...processOutput(""),
115 exitCode: ChildProcessSpawner.ExitCode(128),
116 stderr: "fatal: not a git repository",
117 }
118 : processOutput("true\n");
119 }
120 if (command === "rev-parse --show-toplevel") {
121 return processOutput("/repo\n");
122 }
123 if (command === "rev-parse --git-common-dir") {
124 return processOutput("/repo/.git\n");
125 }
126 return processOutput("");
127 }),
128 }),
129 ),
130 );
131119
132 return Effect.gen(function* () {120 yield* Effect.gen(function* () {
133 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;121 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;
122 assert.equal((yield* registry.detect({ cwd: repoDir }))?.repository.rootPath, repoDir);
134123
135 assert.equal(yield* registry.detect({ cwd: "/repo" }), null);124 yield* fs.remove(path.join(repoDir, ".git"), { recursive: true });
136 assert.equal((yield* registry.detect({ cwd: "/repo" }))?.repository.rootPath, "/repo");125
137 assert.equal(insideWorkTreeChecks, 2);126 assert.equal(yield* registry.detect({ cwd: repoDir }), null);
138 }).pipe(Effect.provide(layer));127 assert.equal(calls.filter((call) => call === "rev-parse --is-inside-work-tree").length, 2);
139 });128 }).pipe(Effect.provide(makeDiskBackedLayer(repoDir, calls)));
129 }).pipe(Effect.provide(NodeServices.layer)),
130 );
131
132 it.effect("detects again when git init creates a repository inside a cached one", () =>
133 Effect.gen(function* () {
134 const fs = yield* FileSystem.FileSystem;
135 const path = yield* Path.Path;
136 const parentDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-vcs-registry-" });
137 const projectDir = path.join(parentDir, "project");
138 yield* fs.makeDirectory(path.join(parentDir, ".git"));
139 yield* fs.makeDirectory(projectDir);
140 const calls: string[] = [];
141
142 yield* Effect.gen(function* () {
143 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;
144 assert.equal((yield* registry.detect({ cwd: projectDir }))?.repository.rootPath, parentDir);
145
146 yield* fs.makeDirectory(path.join(projectDir, ".git"));
147
148 assert.equal(
149 (yield* registry.detect({ cwd: projectDir }))?.repository.rootPath,
150 projectDir,
151 );
152 }).pipe(Effect.provide(makeDiskBackedLayer(parentDir, calls)));
153 }).pipe(Effect.provide(NodeServices.layer)),
154 );
155
156 it.effect("detects again when git init creates a repository between the cwd and its root", () =>
157 Effect.gen(function* () {
158 const fs = yield* FileSystem.FileSystem;
159 const path = yield* Path.Path;
160 const parentDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-vcs-registry-" });
161 const middleDir = path.join(parentDir, "a");
162 const cwd = path.join(middleDir, "b");
163 yield* fs.makeDirectory(path.join(parentDir, ".git"));
164 yield* fs.makeDirectory(cwd, { recursive: true });
165 const calls: string[] = [];
166
167 yield* Effect.gen(function* () {
168 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;
169 assert.equal((yield* registry.detect({ cwd }))?.repository.rootPath, parentDir);
170
171 yield* fs.makeDirectory(path.join(middleDir, ".git"));
172
173 assert.equal((yield* registry.detect({ cwd }))?.repository.rootPath, middleDir);
174 }).pipe(Effect.provide(makeDiskBackedLayer(parentDir, calls)));
175 }).pipe(Effect.provide(NodeServices.layer)),
176 );
177
178 it.effect("detects a repository created after a negative lookup", () =>
179 Effect.gen(function* () {
180 const fs = yield* FileSystem.FileSystem;
181 const path = yield* Path.Path;
182 const repoDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-vcs-registry-" });
183 const calls: string[] = [];
184
185 yield* Effect.gen(function* () {
186 const registry = yield* VcsDriverRegistry.VcsDriverRegistry;
187 assert.equal(yield* registry.detect({ cwd: repoDir }), null);
188
189 yield* fs.makeDirectory(path.join(repoDir, ".git"));
190
191 assert.equal((yield* registry.detect({ cwd: repoDir }))?.repository.rootPath, repoDir);
192 assert.equal(calls.filter((call) => call === "rev-parse --is-inside-work-tree").length, 2);
193 }).pipe(Effect.provide(makeDiskBackedLayer(repoDir, calls)));
194 }).pipe(Effect.provide(NodeServices.layer)),
195 );
140});196});
apps/server/src/vcs/VcsDriverRegistry.ts+61-4
...@@ -3,7 +3,9 @@ import * as Context from "effect/Context";...@@ -3,7 +3,9 @@ import * as Context from "effect/Context";
3import * as Duration from "effect/Duration";3import * as Duration from "effect/Duration";
4import * as Effect from "effect/Effect";4import * as Effect from "effect/Effect";
5import * as Exit from "effect/Exit";5import * as Exit from "effect/Exit";
6import * as FileSystem from "effect/FileSystem";
6import * as Layer from "effect/Layer";7import * as Layer from "effect/Layer";
8import * as Path from "effect/Path";
79
8import type { VcsDriverKind, VcsError, VcsRepositoryIdentity } from "@t3tools/contracts";10import type { VcsDriverKind, VcsError, VcsRepositoryIdentity } from "@t3tools/contracts";
9import { VcsUnsupportedOperationError } from "@t3tools/contracts";11import { VcsUnsupportedOperationError } from "@t3tools/contracts";
...@@ -12,7 +14,10 @@ import * as VcsProjectConfig from "./VcsProjectConfig.ts";...@@ -12,7 +14,10 @@ import * as VcsProjectConfig from "./VcsProjectConfig.ts";
12import * as VcsDriver from "./VcsDriver.ts";14import * as VcsDriver from "./VcsDriver.ts";
1315
14const DETECTION_CACHE_CAPACITY = 2_048;16const DETECTION_CACHE_CAPACITY = 2_048;
15const DETECTION_CACHE_TTL = Duration.seconds(2);17// Status polls detect every open cwd each tick, and detection costs three git
18// processes. `detect` re-checks each hit against the disk, so this TTL only
19// bounds rare changes those stats cannot see.
20const DETECTION_CACHE_TTL = Duration.minutes(5);
1621
17export interface VcsDriverResolveInput {22export interface VcsDriverResolveInput {
18 readonly cwd: string;23 readonly cwd: string;
...@@ -61,6 +66,8 @@ function parseDetectionCacheKey(key: string): {...@@ -61,6 +66,8 @@ function parseDetectionCacheKey(key: string): {
61}66}
6267
63export const make = Effect.gen(function* () {68export const make = Effect.gen(function* () {
69 const fileSystem = yield* FileSystem.FileSystem;
70 const path = yield* Path.Path;
64 const projectConfig = yield* VcsProjectConfig.VcsProjectConfig;71 const projectConfig = yield* VcsProjectConfig.VcsProjectConfig;
65 const git = yield* GitVcsDriver.makeVcsDriver;72 const git = yield* GitVcsDriver.makeVcsDriver;
66 const drivers: Partial<Record<VcsDriverKind, VcsDriver.VcsDriver["Service"]>> = {73 const drivers: Partial<Record<VcsDriverKind, VcsDriver.VcsDriver["Service"]>> = {
...@@ -111,8 +118,44 @@ export const make = Effect.gen(function* () {...@@ -111,8 +118,44 @@ export const make = Effect.gen(function* () {
111 return yield* detectWithDriver("git", git, input.cwd);118 return yield* detectWithDriver("git", git, input.cwd);
112 });119 });
113120
114 const detectionCache = yield* Cache.makeWith<string, VcsDriverHandle | null, VcsError>(121 // The cwd and each parent below the repository root. A new `.git` in any of
115 (key) => detectResolvedKind(parseDetectionCacheKey(key)),122 // them means `git init` made a nested repository. Falls back to the cwd alone
123 // when the root is not above it, such as a cwd reached through a symlink.
124 const foldersBelowRoot = (cwd: string, rootPath: string) => {
125 const relative = path.relative(path.resolve(rootPath), path.resolve(cwd));
126 if (relative.startsWith("..") || path.isAbsolute(relative)) return [cwd];
127 return Array.from({ length: relative.split(path.sep).length }, (_, levelsUp) =>
128 path.resolve(cwd, ...Array<string>(levelsUp).fill("..")),
129 );
130 };
131
132 // What `detect` re-checks on every cache hit, using stats instead of git.
133 const readDiskState = (cwd: string, repository: VcsRepositoryIdentity) =>
134 Effect.all({
135 gitEntries: Effect.forEach(foldersBelowRoot(cwd, repository.rootPath), (folder) =>
136 fileSystem.exists(path.join(folder, ".git")),
137 ),
138 repositoryOnDisk: Effect.forEach(
139 repository.metadataPath === null
140 ? [cwd]
141 : [cwd, path.resolve(cwd, repository.metadataPath)],
142 (target) => fileSystem.exists(target),
143 ).pipe(Effect.map((results) => results.every(Boolean))),
144 }).pipe(Effect.orElseSucceed(() => null));
145
146 const detectionCache = yield* Cache.makeWith<
147 string,
148 { readonly handle: VcsDriverHandle; readonly gitEntries: ReadonlyArray<boolean> } | null,
149 VcsError
150 >(
151 (key) =>
152 Effect.gen(function* () {
153 const input = parseDetectionCacheKey(key);
154 const handle = yield* detectResolvedKind(input);
155 if (handle === null) return null;
156 const disk = yield* readDiskState(input.cwd, handle.repository);
157 return { handle, gitEntries: disk?.gitEntries ?? [] };
158 }),
116 {159 {
117 capacity: DETECTION_CACHE_CAPACITY,160 capacity: DETECTION_CACHE_CAPACITY,
118 timeToLive: Exit.match({161 timeToLive: Exit.match({
...@@ -122,10 +165,24 @@ export const make = Effect.gen(function* () {...@@ -122,10 +165,24 @@ export const make = Effect.gen(function* () {
122 },165 },
123 );166 );
124167
168 // A hit is stale when its worktree or `.git` folder was removed, or when
169 // `git init` created a nested repository between the cwd and its root.
125 const detect: VcsDriverRegistry["Service"]["detect"] = Effect.fn("VcsDriverRegistry.detect")(170 const detect: VcsDriverRegistry["Service"]["detect"] = Effect.fn("VcsDriverRegistry.detect")(
126 function* (input) {171 function* (input) {
127 const requestedKind = yield* projectConfig.resolveKind(input);172 const requestedKind = yield* projectConfig.resolveKind(input);
128 return yield* Cache.get(detectionCache, detectionCacheKey({ cwd: input.cwd, requestedKind }));173 const key = detectionCacheKey({ cwd: input.cwd, requestedKind });
174 const cached = yield* Cache.get(detectionCache, key);
175 if (cached === null) return null;
176 const disk = yield* readDiskState(input.cwd, cached.handle.repository);
177 if (
178 disk?.repositoryOnDisk &&
179 disk.gitEntries.length === cached.gitEntries.length &&
180 disk.gitEntries.every((exists, index) => exists === cached.gitEntries[index])
181 ) {
182 return cached.handle;
183 }
184 yield* Cache.invalidate(detectionCache, key);
185 return (yield* Cache.get(detectionCache, key))?.handle ?? null;
129 },186 },
130 );187 );
131188