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:
+5
-1
@@ -339,7 +339,11 @@ function serviceHealth(service) {
|
||||
}
|
||||
|
||||
async function heartbeat() {
|
||||
await request('/api/agent/heartbeat', { method: 'POST', body: JSON.stringify({ version: VERSION, system: systemInfo(), engine: engineHealth() }) });
|
||||
const engine = engineHealth();
|
||||
// Report the resources actually held locally; the panel re-dispatches any
|
||||
// expected resource missing from this list (e.g. after a state wipe).
|
||||
const resources = readResources().map((resource) => resource && resource.id).filter((value) => typeof value === 'string' && value);
|
||||
await request('/api/agent/heartbeat', { method: 'POST', body: JSON.stringify({ version: VERSION, system: systemInfo(), engine, resources }) });
|
||||
try { fs.writeFileSync('/etc/nexusgate/last-heartbeat.json', `${JSON.stringify({ at:new Date().toISOString() })}\n`, { mode:0o600 }); }
|
||||
catch (error) { log('Heartbeat reached controller but readiness file failed', error.message); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user