Runner: Proxy und Startseite, register/wake (R12)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 21:53:41 +00:00
1 parent 6cd50bba9f
commit 4afe7eb5cd
7 files changed
+360 -2

No files matched your search

+19 -1
View File
@@ -42,6 +42,7 @@ export function createDev({
setTimer = (fn, ms) => setTimeout(fn, ms).unref?.() ?? 0, prepareDirs = defaultPrepareDirs,
rmDir = (p) => nodeFs.rm(p, { recursive: true, force: true }),
}) {
const specs = new Map(); // R12: letzte Job-Spezifikation je sub (bleibt auch im Zustand 'sleeping')
const entries = new Map(); // sub ⇒ { sub, state, sha, lastUsed, log, port, job, release, promise, cancelled }
const sleep = (ms) => new Promise((r) => setTimer(r, ms));
const isRunning = (e) => e.state === 'online' || e.state === 'starting';
@@ -123,6 +124,7 @@ export function createDev({
}
async function ensure(sub, job) {
specs.set(sub, job);
const cur = entries.get(sub);
if (cur && cur.sha === job.sha) {
if (cur.state === 'failed' && now() - cur.failedAt < RETRY_MS) return { state: 'failed' }; // nicht öfter als alle 60 s neu versuchen
@@ -142,8 +144,24 @@ export function createDev({
return { state: 'starting' };
}
// R12: Spezifikation merken, ohne zu starten. Läuft der sub mit anderem sha, wird nach den üblichen Regeln neu gestartet.
async function register(sub, job) {
const cur = entries.get(sub);
if (cur && isRunning(cur) && cur.sha !== job.sha) return ensure(sub, job);
specs.set(sub, job);
if (cur && cur.sha === job.sha && (cur.state === 'online' || cur.state === 'starting' || cur.state === 'failed')) return { state: cur.state };
return { state: 'sleeping' };
}
// R12: Start mit der gemerkten Spezifikation (Proxy kennt nur die Subdomain).
async function wake(sub) {
const job = specs.get(sub);
if (!job) return { state: 'unknown' };
return ensure(sub, job);
}
const touch = (sub) => { const e = entries.get(sub); if (e) e.lastUsed = now(); };
async function stop(sub) {
specs.delete(sub); // 'off': Spezifikation vergessen, bis das Portal neu registriert
const e = entries.get(sub);
if (!e) return;
await shutdown(e, 'off');
@@ -166,5 +184,5 @@ export function createDev({
}
const idle = () => Promise.all([...entries.values()].map((e) => e.promise)).then(() => {});
return { ensure, touch, stop, list, status, sweep, cleanupOrphans, idle };
return { ensure, register, wake, touch, stop, list, status, sweep, cleanupOrphans, idle };
}