returnr.ok?`${r.count} Ressourcen abgeglichen`:`Abgleich fehlgeschlagen: ${r.error}`;// Ausfall ist ein Zustand der Instanz, kein Jobfehler (nächster Lauf folgt planmäßig)
const[rows]=awaitc.query("SELECT * FROM jobs WHERE status IN ('scheduled','retrying') AND run_at <= UTC_TIMESTAMP(3) ORDER BY run_at LIMIT 1 FOR UPDATE SKIP LOCKED")asany;
job=rows[0];
if(!job){awaitc.rollback();returnfalse;}
awaitc.query("UPDATE jobs SET status='running', locked_at=UTC_TIMESTAMP(3), attempts=attempts+1 WHERE id=?",[job.id]);
awaitpool.query("UPDATE jobs SET status='succeeded', locked_at=NULL, last_error=? WHERE id=?",[note??null,job.id]);
}catch(e){
constmsg=String((easError).message).slice(0,500);
constjf=einstanceofJobFailure?e : null;
constnoRetry=jf?!jf.retry : false;
constdead=noRetry||attempt>=job.max_attempts;
constfinal=jf?.finalStatus??'needs_review';
awaitpool.query("UPDATE jobs SET status=?, locked_at=NULL, last_error=?, run_at=DATE_ADD(UTC_TIMESTAMP(3), INTERVAL ? SECOND) WHERE id=?",[dead?final:'retrying',msg,jf?.delaySec??backoff(attempt),job.id]);
// Destruktive Aufträge werden nach einem Absturz NICHT automatisch wiederholt, sondern zur Prüfung markiert.
awaitpool.query("UPDATE jobs SET status='needs_review', locked_at=NULL, last_error='Unterbrochen während der Ausführung; Ergebnis beim Provider prüfen' WHERE status='running' AND (JSON_VALUE(payload, '$.destructive') IN ('1','true') OR JSON_VALUE(payload, '$.action') = 'terminate') AND locked_at < DATE_SUB(UTC_TIMESTAMP(3), INTERVAL 5 MINUTE)");
const[r]=awaitpool.query("UPDATE jobs SET status='retrying', locked_at=NULL, last_error='Worker-Neustart während der Ausführung' WHERE status='running' AND locked_at < DATE_SUB(UTC_TIMESTAMP(3), INTERVAL 5 MINUTE)")asany;
if(r.affectedRows)log(`${r.affectedRows} hängende Aufträge wieder eingeplant`);