Publish quixos-nix-helpers from 806ea0e9f41340acf119b7374f5150ef5b378074

This commit is contained in:
Quixos Subtree Publisher
2026-10-08 11:31:16 +00:00
3 changed files with 30 additions and 2 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"version": 1, "version": 1,
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos", "sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
"sourceCommit": "57684c7548883dc4fc25dc8f943c7a43b3489fcf", "sourceCommit": "806ea0e9f41340acf119b7374f5150ef5b378074",
"sourcePath": "quixos-instance/quixos-nix-helpers", "sourcePath": "quixos-instance/quixos-nix-helpers",
"exportName": "quixos-nix-helpers", "exportName": "quixos-nix-helpers",
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git" "mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
+15
View File
@@ -148,6 +148,11 @@ export async function serveRestrictedRegistry(config, io = process) {
engines = new Set(), engines = new Set(),
idleEngines = []; idleEngines = [];
const metrics = { starts: 0, reused: 0, completed: 0, peakRSSBytes: 0 }; const metrics = { starts: 0, reused: 0, completed: 0, peakRSSBytes: 0 };
const changed = () => {
try {
config.onChange?.();
} catch {}
};
let buffered = Buffer.alloc(0), let buffered = Buffer.alloc(0),
stopped = false, stopped = false,
failure; failure;
@@ -244,6 +249,7 @@ export async function serveRestrictedRegistry(config, io = process) {
// physical memory remains the supervising process/cgroup's contract. // physical memory remains the supervising process/cgroup's contract.
if (rss <= 128 * 1024 * 1024) { if (rss <= 128 * 1024 * 1024) {
idleEngines.push(engine); idleEngines.push(engine);
engine.idleUntil = Date.now() + limits.engineIdleMs;
engine.idleTimer = setTimeout(() => void destroyEngine(engine).catch(fail), limits.engineIdleMs); engine.idleTimer = setTimeout(() => void destroyEngine(engine).catch(fail), limits.engineIdleMs);
} else await destroyEngine(engine); } else await destroyEngine(engine);
} else await destroyEngine(engine); } else await destroyEngine(engine);
@@ -300,6 +306,7 @@ export async function serveRestrictedRegistry(config, io = process) {
} finally { } finally {
engines.delete(engine); engines.delete(engine);
await engine.release?.(); await engine.release?.();
changed();
} }
})(); })();
return engine.destroying; return engine.destroying;
@@ -418,6 +425,7 @@ export async function serveRestrictedRegistry(config, io = process) {
}, },
); );
metrics.starts++; metrics.starts++;
changed();
engine.exited = new Promise((resolve) => { engine.exited = new Promise((resolve) => {
engine.child.once("exit", resolve); engine.child.once("exit", resolve);
engine.child.once("error", resolve); engine.child.once("error", resolve);
@@ -462,6 +470,9 @@ export async function serveRestrictedRegistry(config, io = process) {
executionMs: call.executionMs ?? null, executionMs: call.executionMs ?? null,
totalMs: performance.now() - call.receivedAt, totalMs: performance.now() - call.receivedAt,
}; };
metrics.lastFailure =
reply.status === "failed" && /^[A-Z0-9_]{1,128}$/.test(reply.error?.code) ? reply.error.code : null;
changed();
send(call.cancellationReply ?? reply); send(call.cancellationReply ?? reply);
pump(); pump();
})()); })());
@@ -470,6 +481,7 @@ export async function serveRestrictedRegistry(config, io = process) {
const { message } = call; const { message } = call;
call.startedAt = performance.now(); call.startedAt = performance.now();
active.set(message.invocation, call); active.set(message.invocation, call);
changed();
const terminate = (code) => { const terminate = (code) => {
if (!call.open) return; if (!call.open) return;
void finish(call, fixedError(code), { void finish(call, fixedError(code), {
@@ -687,6 +699,9 @@ export async function serveRestrictedRegistry(config, io = process) {
queued: queued.length, queued: queued.length,
engines: engines.size, engines: engines.size,
idle: idleEngines.length, idle: idleEngines.length,
idleDeadline: idleEngines.length
? new Date(Math.min(...idleEngines.map((engine) => engine.idleUntil))).toISOString()
: null,
}), }),
}; };
} }
+14 -1
View File
@@ -570,12 +570,25 @@ test("an expired frame token cannot borrow a later invocation's broker", async (
}); });
test("idle engines evict without a graph poll and restart with fresh state", async () => { test("idle engines evict without a graph poll and restart with fresh state", async () => {
const f = await fixture(registry("return request.input;"), { engineIdleMs: 30 }); const updates = [];
const f = await fixture(registry("return request.input;"), {
engineIdleMs: 30,
onChange: () => updates.push(f.stats()),
});
try { try {
f.start("first"); f.start("first");
assert.equal((await f.receive()).output, "first"); assert.equal((await f.receive()).output, "first");
await new Promise((resolve) => setTimeout(resolve, 100)); await new Promise((resolve) => setTimeout(resolve, 100));
assert.equal(f.stats().engines, 0); assert.equal(f.stats().engines, 0);
assert.ok(
updates.some((s) => s.active > 0),
"Inspectors observe active invocation admission",
);
assert.ok(
updates.some((s) => s.idle > 0 && s.idleDeadline),
"Idle eviction deadline is visible",
);
assert.equal(updates.at(-1).engines, 0, "Eviction pushes an update without a graph poll");
f.start("second"); f.start("second");
assert.equal((await f.receive()).output, "second"); assert.equal((await f.receive()).output, "second");
assert.equal(f.stats().starts, 2); assert.equal(f.stats().starts, 2);