kundencenter/migrations/032_jobs_lease.sql

7 lines
564 B
MySQL
Raw Normal View History

fix(worker): Lease/Heartbeat statt starrer 5-Minuten-Grenze bei Jobwiederaufnahme Nightbot-Befund #99/#16 (P1): recoverStale gab "running"-Jobs nach starren fünf Minuten wieder frei, ohne zu prüfen, ob der ursprüngliche Worker noch aktiv daran arbeitet. Ein legitim länger laufender Job (z. B. ein langsamer Connector-Abgleich) konnte dadurch von einem zweiten Worker parallel erneut gestartet werden – Doppelausführung, z. B. doppelte Provisionierung oder doppelter Mailversand. - Migration 032: jobs.lease_id (pro Übernahme neu vergeben) und jobs.locked_by (Worker-Kennung, nur Diagnose). - runOnce vergibt beim Übernehmen einen frischen Lease und hält locked_at per Heartbeat alle 60 s aktuell, solange der Handler läuft. Jedes Abschluss-UPDATE (Erfolg wie Fehler) ist an genau diesen Lease gebunden (WHERE lease_id = ?); hat recoverStale die Zeile inzwischen doch freigegeben, verpufft ein verspätetes Ergebnis wirkungslos statt den neuen Versuch zu überschreiben. - recoverStale reißt jetzt nur noch Jobs an sich, deren Heartbeat tatsächlich ausgeblieben ist (locked_at älter als 5 Minuten), nicht mehr solche, die einfach nur lange laufen. Löscht lease_id beim Freigeben mit. Verifiziert: (a) SQL-Ebene direkt durchexerziert – frischer Heartbeat verhindert das Anreißen, ausgebliebener Heartbeat löst es aus, ein verspätetes Abschluss-UPDATE mit altem Lease betrifft 0 Zeilen; (b) echter Code über runOnce/recoverStale gegen die Testdatenbank – Job durchläuft Übernahme, Fehlschlag, lease-gebundenes Abschluss-UPDATE korrekt. Worker neu gestartet, läuft fehlerfrei, 1437 bestehende Jobs weiterhin 'succeeded'. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 11:41:43 +02:00
-- Nightbot-Befund #99/#16: recoverStale gab "running"-Jobs nach starren 5 Minuten wieder frei, ohne zu prüfen,
-- ob der ursprüngliche Worker noch aktiv daran arbeitet. Ein legitim länger laufender Job konnte dadurch von
-- einem zweiten Worker parallel erneut gestartet werden (Doppelausführung).
ALTER TABLE jobs
ADD COLUMN lease_id CHAR(36) NULL, -- pro Übernahme neu vergeben; nur der aktuelle Lease darf das Ergebnis schreiben
ADD COLUMN locked_by VARCHAR(100) NULL; -- Worker-Kennung (Host:PID:Zufall) für Diagnose, kein Sicherheitsmerkmal