Files
orca/src/shared/promise-timeout-fallback.ts
T
Neil b82a8791f5 perf(runtime): resolve an explicit worktree id without scanning every repo (#14399)
`resolveWorktreeSelector` resolved every selector kind from the whole-fleet snapshot, so a targeted `id:<repoId>::<path>` lookup fanned `git worktree list` across every registered repo to answer a question about one of them. With a cold scan cache -- app startup, or the first lookup after a mutation clears the snapshot -- that is one subprocess per repo, ~17ms each, to find a worktree whose owning repo the id already names. Measured on a ten-repo fleet: one `id:` lookup scans 10 repos before and 1 after.

Scope only `id:`. Every other selector kind is matched across the fleet and its `selector_ambiguous` contract is defined over all repos, so scoping `branch:`, `name:`, `issue:`, or a bare selector would silently pick a winner where they correctly refuse today. A test pins that: `branch:main` across ten repos still throws `selector_ambiguous` and still scans all ten.

Lineage stays correct because edges are intra-repo by construction. The scoped path returns null and falls back whenever that does not hold: a repo id registered on several execution hosts, an unknown repo id, or a worktree the scoped scan does not contain. A warm fleet snapshot always wins.

Row resolution moves out of orca-runtime.ts into repo-worktree-row-resolution.ts, which owns no state -- the cache-aware scan and folder-workspace stamping are injected. orca-runtime.ts ends up 65 lines shorter than before despite the added feature.
2026-08-14 01:15:30 -07:00

21 lines
694 B
TypeScript

/**
* Resolve `fallback` when `promise` has not settled within `timeoutMs`.
*
* Note that a rejection also resolves the fallback, so a caller that needs to tell "timed out" apart
* from "failed" must absorb the rejection itself before handing the promise over.
*/
export function withTimeout<T>(promise: Promise<T>, timeoutMs: number, fallback: T): Promise<T> {
let timeout: ReturnType<typeof setTimeout> | null = null
return new Promise<T>((resolve) => {
timeout = setTimeout(() => resolve(fallback), timeoutMs)
promise.then(
(value) => resolve(value),
() => resolve(fallback)
)
}).finally(() => {
if (timeout) {
clearTimeout(timeout)
}
})
}