fix: enforce one Pi runtime per user

This commit is contained in:
2026-07-21 16:13:17 +02:00
parent a040c083cc
commit 00761ae2ca
4 changed files with 125 additions and 19 deletions
+8 -9
View File
@@ -97,14 +97,6 @@ export function sessionRoutes(
return true;
};
const releaseFinalizedRuntimes = async (): Promise<void> => {
await Promise.all([...boundRuntimes.entries()].map(([id, rt]) =>
withSessionLifecycle(id, () => releaseIfFinalized(id, rt)).catch((error: unknown) => {
console.error(`[session:${id}] stale runtime cleanup failed:`, error);
}),
));
};
const bindRuntime = (
id: string, rt: ReturnType<PiProcessManager["createFor"]>, runner: any, workspace?: string,
) => {
@@ -208,7 +200,10 @@ export function sessionRoutes(
let s: Settings;
try { s = await d.getSettings(principal); } catch { return storageFailure(reply); }
const runner = runnerFor(principal);
await releaseFinalizedRuntimes();
// A persisted session is resumable without keeping Pi alive. New work replaces every
// runtime owned by this principal, while runtimes belonging to other users remain intact.
// Optional chaining preserves the deliberately narrow manager stubs used by route tests.
for (const id of d.mgr.teardownForPrincipal?.(principal) ?? []) boundRuntimes.delete(id);
const ensure = await d.readiness.ensure(s.workspace ?? "", principal);
if (!ensure.ok) return reply.code(503).send({ error: READINESS_FAILURE_MESSAGE });
// Local-only: verify the DWH is reachable BEFORE creating the session, so a dropped
@@ -388,6 +383,10 @@ export function sessionRoutes(
}
}
for (const stoppedId of d.mgr.teardownForPrincipal?.(principal) ?? []) {
boundRuntimes.delete(stoppedId);
}
let rt: ReturnType<PiProcessManager["createFor"]> | undefined;
try {
if (current) {