mirror of
https://github.com/stablyai/orca.git
synced 2026-09-25 16:02:38 +00:00
`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.
21 lines
694 B
TypeScript
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)
|
|
}
|
|
})
|
|
}
|