fix(worker): ensure reconciled boxes before acquire

This commit is contained in:
Gabriel Brown
2026-07-10 17:04:41 -04:00
parent 284f7ea52b
commit 0b5a2c0411
2 changed files with 35 additions and 5 deletions
+11 -5
View File
@@ -13,6 +13,7 @@ export type BoxHandle = { boxName: string; release: () => void };
type Box = {
name: string;
initialized: boolean;
refs: Set<symbol>;
idleTimer?: ReturnType<typeof setTimeout>;
};
@@ -71,21 +72,26 @@ export const acquireUserBox = (args: {
}): Promise<BoxHandle> =>
withLock(args.username, async () => {
let box = boxes.get(args.username);
let needsEnsure = false;
if (box?.idleTimer) {
clearTimeout(box.idleTimer);
box.idleTimer = undefined;
}
if (!box) {
box = { name: userContainerName(args.username), refs: new Set() };
box = {
name: userContainerName(args.username),
initialized: false,
refs: new Set(),
};
boxes.set(args.username, box);
needsEnsure = true;
}
// Register the ref before the slow Docker call so a failed acquire can
// release it without leaking registry state.
const handle = makeHandle(args.username, box);
try {
if (needsEnsure) box.name = await ensureUserContainer(args);
if (!box.initialized) {
box.name = await ensureUserContainer(args);
box.initialized = true;
}
return handle;
} catch (error) {
handle.release();
@@ -103,7 +109,7 @@ export const reconcileExistingBoxes = async (): Promise<void> => {
for (const name of names) {
const username = name.replace(/^spoon-box-/, '');
if (boxes.has(username)) continue;
const box: Box = { name, refs: new Set() };
const box: Box = { name, initialized: false, refs: new Set() };
boxes.set(username, box);
scheduleReapIfIdle(username);
}