feat: heartbeat reconciliation — panel re-dispatches resources a node lost

Agents (Go + Node) now report the resource IDs they actually hold in
each heartbeat. When an expected resource is missing locally (e.g. the
node's /etc/nexusgate state was wiped and only the agent restarted, so
no re-enrollment happens), the panel re-queues applies for just the
affected nodes via reconcileFromHeartbeat: gated on no queued/running
jobs for the server (in-flight jobs are never failed by this path) and
throttled to one trigger per server per 120s, audited as
system:heartbeat. reconcileServer gains optional onlyNodeIds /
failInFlight parameters; the enrollment call is unchanged. Heartbeats
without a resources array (old agents) behave exactly as before.
This commit is contained in:
aaaamoooo
2026-10-20 07:46:33 +00:00
parent f2b7d8e181
commit abb1a4344b
5 changed files with 342 additions and 46 deletions
+8
View File
@@ -308,6 +308,14 @@ async function handleAgent(req, res, pathname) {
: server.engine || null;
}
});
// Agents that report their locally held resource IDs get automatic
// re-dispatch of anything the panel expects but the node lost (e.g. a
// wiped /etc/nexusgate with no re-enrollment). Reports without the field
// (older agents) skip this entirely.
if (Array.isArray(body.resources)) {
try { await orchestrator.reconcileFromHeartbeat(agent.serverId, body.resources); }
catch (error) { console.error('Heartbeat reconciliation failed:', error); }
}
sendJson(res, 200, { ok: true, serverTime: nowIso() });
return true;
}