Nebenläufigkeit: Events, Listener, Jobs¶
Eine Verzeichnungseinheit trägt Felder, die aus anderen Daten folgen: ihren Pfad in der Tektonik, ihre Tiefe, das Freigabejahr, den Volltextindex, die über den Teilbaum aggregierte Datierung. Diese Werte sind materialisiert — sie stehen in Spalten, statt bei jeder Abfrage neu gerechnet zu werden.
Materialisierung erkauft schnelle Abfragen mit dem Zwang, die Werte konsistent zu halten. Genau das leistet die Ereignis- und Job-Schicht. Wer sie versteht, versteht, warum eine scheinbar einfache Änderung an einem Objekt eine Kette von Hintergrundaufträgen auslöst.
Das Muster¶
Anton koppelt Domänenoperationen und Nachpflege lose über Laravel-Events:
Operation am AntonObject → Domain-Event → Listener → Job (Queue)
Der Kern liegt in den Model-Hooks von AntonObject (booted()) und in
EventServiceProvider. Die Nachpflege läuft über die Queue, weil sie ganze
Teilbäume berühren kann — bei einer Closure Table ist das potenziell teuer.
Warum asynchron und idempotent¶
Zwei Entwurfsentscheidungen erklären fast alles:
Teilbaum-Arbeit gehört in die Queue. Ein Verschieben schreibt Pfade und Tiefen aller Nachkommen um; eine Titeländerung kann den Volltext des ganzen Teilbaums betreffen. Solche Arbeit synchron im Request zu erledigen, würde ihn sprengen — deshalb Jobs mit grosszügigen Timeouts und Retries.
Die Jobs sind wiederholbar. Jeder rechnet den Zielzustand aus den
Quelldaten neu, statt Deltas fortzuschreiben. Das macht sie idempotent: Ein
zweiter Lauf schadet nicht, ein verlorener Lauf lässt sich nachholen. Genau
darauf beruht die Reparaturfähigkeit — anton:doctor und
RepairAllDerivedAttributes können jederzeit den konsistenten Zustand
wiederherstellen.
Domain-Events werden bei Massenoperationen unterdrückt¶
Ein wichtiges Detail: Beim Anlegen vieler Datensätze (create_bulk) und während
eines Verschiebens setzt der Code $suppressDomainEvents = true und stösst die
Nachpflege einmal am Ende an, statt pro Objekt. Sonst würde eine
Bulk-Operation Hunderte redundanter Jobs erzeugen. Wer eine neue Massenoperation
schreibt, muss dieses Muster kennen und selbst dafür sorgen, dass Pfade, Daten
und Volltext danach einmal aktualisiert werden.
Die abgeleiteten Felder¶
| Feld | Wird neu berechnet bei | Job |
|---|---|---|
path, real_depth |
Anlegen, Verschieben | UpdatePaths |
| aggregierte Datierung | Datumsänderung im Teilbaum | UpdateDates |
full_text, full_text_intern |
Titel-/Inhaltsänderung, neuen Medien | RefreshFulltext |
release_year_calculated |
Schutzfrist-/Datumsänderung | über die Nachkommen-Pflege |
private, status_of_description_id |
Änderung auf einem Vorfahren | Vererbung an alle Nachkommen |
RefreshFulltext illustriert eine allgemeine Vorsichtsregel der Schicht: Bei
wenigen IDs läuft es in-process, bei vielen oder der ganzen Datenbank in einem
eigenen PHP-Prozess — zur Speicher-Isolation, damit ein grosser Rebuild den
Worker nicht sprengt.
Voraussetzung: der Supervisor läuft¶
Die ganze Schicht setzt voraus, dass die Queue abgearbeitet wird. Steht der Supervisor nicht, stauen sich die Jobs ohne Fehlermeldung, und die abgeleiteten Felder veralten still. Der Reiter Supervisor im Anton Doctor zeigt den Zustand — die erste Station bei «Änderungen kommen nicht an».
Kein Scheduler auf den Servern¶
Der Laravel-Scheduler (schedule:run) läuft auf den Produktionsservern nicht
(vgl. den Kommentar in app/Console/Kernel.php). Wiederkehrende Aufgaben —
Integritätsprüfungen, Disk-Messung, Normdaten-Abgleich — werden deshalb pro
Installation als Cronjob eingerichtet, nicht über den Scheduler. Wer eine
periodische Aufgabe braucht, plant sie als Cron ein.