MCPcopy Create free account
hub / github.com/backnotprop/plannotator / createWorktreePool

Function createWorktreePool

packages/shared/worktree-pool.ts:58–164  ·  view source on GitHub ↗
(
  config: WorktreePoolConfig,
  initial?: PoolEntry,
  initialPending?: Promise<PoolEntry>,
)

Source from the content-addressed store, hash-verified

56}
57
58export function createWorktreePool(
59 config: WorktreePoolConfig,
60 initial?: PoolEntry,
61 initialPending?: Promise<PoolEntry>,
62): WorktreePool {
63 const pool = new Map<string, PoolEntry>();
64 const pending = new Map<string, Promise<PoolEntry>>();
65 // FETCH_HEAD is shared per-repo state: a creation's PR-head fetch must not
66 // run while another creation (or the seeded background warmup) is between
67 // its own fetch and `git worktree add`. Serialize all creations through
68 // this chain.
69 let creationChain: Promise<unknown> = Promise.resolve();
70 if (initial) pool.set(initial.prUrl, initial);
71
72 // Seeded background warmup: the initial entry starts ready:false while the
73 // caller builds its checkout (fetch/clone) off the request path. ensure()
74 // awaits the in-flight warmup instead of starting a duplicate creation.
75 // On failure the entry is KEPT as ready:false — resolve() stays undefined so
76 // consumers never receive a path that was never created; same-repo ensure()
77 // can retry creation once the failed warmup is cleared from pending.
78 if (initial && initialPending) {
79 const tracked = initialPending.then(
80 (entry) => {
81 pool.set(initial.prUrl, entry);
82 return entry;
83 },
84 (err) => {
85 pending.delete(initial.prUrl);
86 throw err;
87 },
88 );
89 pending.set(initial.prUrl, tracked);
90 creationChain = tracked.catch(() => {});
91 tracked
92 .then(() => pending.delete(initial.prUrl))
93 .catch(() => {}); // warmup may complete with nobody awaiting it
94 }
95
96 return {
97 get(prUrl) { return pool.get(prUrl); },
98 has(prUrl) { return pool.has(prUrl); },
99 resolve(prUrl) {
100 const entry = pool.get(prUrl);
101 return entry?.ready ? entry.path : undefined;
102 },
103
104 async ensure(runtime, metadata) {
105 const existing = pool.get(metadata.url);
106 if (existing?.ready) return existing;
107
108 const inflight = pending.get(metadata.url);
109 if (inflight) return inflight;
110
111 if (!config.isSameRepo) {
112 throw new Error("Cross-repo pool cannot create worktrees for other PRs");
113 }
114
115 const create = async (): Promise<PoolEntry> => {

Callers 3

index.tsFile · 0.90

Calls 3

deleteMethod · 0.80
resolveMethod · 0.65
setMethod · 0.45

Tested by

no test coverage detected