Worker dashboard: a flock-held slot with an empty file counts as held (label unknown), not free
Seen on igneum-build-1 at 10:39Z on 7 October 2026: both slot files flock-held and empty while two suites ran and three waiters queued, so the header read 0/2. The holder's missing line is the build-server agent's to fix; the collector no longer reports a full box as free either way, and the page shows "held, no holder line" in the lane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
9a6f2606b8
commit
b9e2a0dce7
3 changed files with 5 additions and 0 deletions
|
|
@ -130,6 +130,7 @@ export function parseLockDir(files, { day, now, aliveFn } = {}) {
|
|||
const alive = line && aliveFn ? aliveFn(line.pid) : null;
|
||||
const isHeld = f.held ?? (line ? alive !== false : false);
|
||||
if (line && isHeld) held.push({ slot: f.name, ...line, kind: deriveKind(line) });
|
||||
else if (f.held === true) held.push({ slot: f.name, pid: null, since: null, waited_s: null, label: null, agent: null, worktree: null, crate: null, command: null, target: null, kind: null, nice: null, cores: null, no_line: true }); // the flock is taken but the holder wrote no line (7 Oct 2026: the scheduling-class path on build-1)
|
||||
else free.push(f.name);
|
||||
}
|
||||
held.sort((a, b) => a.slot.localeCompare(b.slot));
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ function renderCrew() {
|
|||
function nowItems() {
|
||||
const out = [];
|
||||
for (const bx of boxesOf(D)) for (const r of bx.running || []) out.push({ where: bx.name, slot: r.slot, title: `${kindLabel(r.kind)}`, sub: `${r.worktree || '?'}/${r.crate || ''}${r.agent ? ' · ' + r.agent : ''}`, cmd: r.command, started_at: r.started_at, kind: r.kind, extra: [r.target || '', classLine(r)].filter(Boolean).join(' · ') });
|
||||
for (const bx of boxesOf(D)) for (const h of (bx.slots && bx.slots.held || []).filter(h => h.no_line && !(bx.running || []).some(r => r.slot === h.slot))) out.push({ where: bx.name, slot: h.slot, title: 'held, no holder line', sub: 'the slot is flock-held but its file is empty (the holder wrote no line)', cmd: '', started_at: null, kind: null, extra: '' });
|
||||
for (const h of (D.mac && D.mac.slots.held) || []) out.push({ where: D.mac.name, slot: h.slot, title: h.slot === 'measure' ? 'measurement' : h.slot.startsWith('run') ? 'functional run' : kindLabel(h.kind), sub: h.worktree || 'this Mac', cmd: h.command || h.label, started_at: h.since, kind: h.kind, extra: h.waited_s ? `waited ${fmtDur(h.waited_s)}` : '' });
|
||||
for (const pc of (D.pcs && D.pcs.machines) || []) if (pc.running) out.push({ where: pc.name, slot: 'relay job', title: `${pc.running.kind} ${pc.running.job}`, sub: pc.running.title || pc.machine || '', cmd: pc.running.stage ? `stage ${pc.running.stage}` : 'reports every 5 min while it runs', started_at: pc.running.started_at, kind: pc.running.kind, extra: pc.running.last_report_at ? `last report ${ago(pc.running.last_report_at)}` : '' });
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ test('lock dir fixture: one held slot, one stale line, one empty, count from slo
|
|||
// an explicit flock verdict overrides the pid check
|
||||
const r2 = parseLockDir(files.map(f => ({ ...f, held: f.name === 'build-1' })), { day: '2026-10-06', now: '2026-10-06T18:00:00Z' });
|
||||
assert.deepEqual(r2.held.map(h => h.slot), ['build-1']);
|
||||
// a flock-held slot whose file is empty is still held (7 Oct 2026 on build-1: two held, both empty, the box full)
|
||||
const r3 = parseLockDir([{ name: 'build-2', text: '', held: true }, { name: 'build-0', text: '', held: false }, { name: 'slots', text: '2' }], { now: '2026-10-07T10:39:00Z' });
|
||||
assert.equal(r3.held.length, 1); assert.equal(r3.held[0].slot, 'build-2'); assert.equal(r3.held[0].no_line, true); assert.deepEqual(r3.free, ['build-0']);
|
||||
});
|
||||
|
||||
test('builds JSONL fixture: five rows, one bad line, newest first, derived fields', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue