v13.39.0 und überträgt die Grundlagen aus Task-Scheduling auf die Paketentwicklung. Wie Provider geladen werden, erfahren Sie unter Interne Struktur der automatischen Paket-Erkennung; zum Veröffentlichen der Konfiguration siehe Paketkonfiguration zusammenführen und cachen.
Nach der Auflösung von Schedule registrieren
In einer gewöhnlichen Laravel-Anwendung registriert derFoundationServiceProvider Schedule::class als Singleton. Die Erzeugung ruft resolveConsoleSchedule() des Console Kernels auf und wendet die Zeitzone der Anwendung sowie den Cache-Store für den Scheduler an.
Ein Paket erweitert diesen gemeinsam genutzten Schedule, statt einfach einen eigenen new Schedule() zu erzeugen. Der folgende Provider geht davon aus, dass Acme\Courier\ per Composer-PSR-4 auf src/ abgebildet ist und das Paket eine config/courier.php enthält.
callAfterResolving() wartet auf die künftige Auflösung, falls der Service noch nicht aufgelöst ist; ist er bereits aufgelöst, holt es ihn und ruft den Callback zusätzlich sofort auf. So gelingt die Registrierung auch dann, wenn ein anderer Provider den Schedule bereits vorher verwendet hat. Details finden Sie unter Hooks nach der Service-Auflösung in Paketen.
runningInConsole() prüft nicht auf einen bestimmten Artisan-Befehl. In diesem Beispiel wird die Nutzung des Schedule über HTTP ausgeschlossen. Außerdem darf der Provider, der den Hook registriert, selbst kein Deferred Provider sein: Läuft boot() nicht rechtzeitig, wird auch der Hook nicht registriert.
Die Registrierung eines Events und die Ausführung einer Aufgabe sind zwei verschiedene Dinge. Das Laden dieses Providers führt den Heartbeat nicht sofort aus. Die Registrierung allein startet auch weder cron noch
schedule:work.Nutzer aktivieren explizit
Die paketseitigeconfig/courier.php ist standardmäßig deaktiviert.
schedule.enabled auf true gesetzt. In diesem Beispiel werden die Werte bei der Registrierung gelesen. Als Standardzeitzone dient UTC; wer eine andere Zeitzone wählt, muss doppelte oder ausgelassene Ausführungen durch die Sommerzeit berücksichtigen.
Da die Konfiguration nur flach zusammengeführt wird, gibt auch der Registrierer für jeden Schlüssel einen Standardwert an. So lässt sich die Aufgabe mit den Grundeinstellungen registrieren, selbst wenn ein teilweises Überschreiben andere Schlüssel des Arrays schedule entfernt.
Doppelte Registrierung im selben Schedule verhindern
Die folgendesrc/CourierSchedule.php registriert einen minimalen Heartbeat, der einen Log-Eintrag schreibt. Mithilfe einer WeakMap sorgt sie dafür, dass dieser Registrierer einem Schedule-Objekt nur einmal etwas hinzufügt.
Schedule::call(), exec() und job() fügen Events zu einem Array hinzu. Es handelt sich nicht um APIs, die Events mit gleichem Namen finden und ersetzen oder Duplikate entfernen.
Event-Namen betreffen auch die Lock-Kompatibilität
name() ist ein Alias von description(), doch die Auswirkung auf den Lock-Namen hängt von der Art des Events ab. Nachfolgend die Standard-Mutex-Namen.
Geben Sie einem CallbackEvent vor
withoutOverlapping() oder onOneServer() einen nicht leeren Namen. Ist kein Name gesetzt, werfen diese Methoden eine Exception.
job() verwendet normalerweise etwa den Namen der Job-Klasse als Anfangsnamen. Registrieren Sie denselben Job jedoch mit unterschiedlichen Argumenten oder Zielen, geben Sie pro Ziel explizit einen Namen an. Allein durch andere Argumente ergibt sich nicht automatisch ein anderer Anfangsname.
SyncCatalogJob ist ein Beispiel für eine vom Paket bereitgestellte Job-Klasse. Wie Jobs implementiert werden, erfahren Sie unter Queues und Jobs.
Ändern Sie Name, Befehl oder Cron-Ausdruck, ändert sich je nach Event-Art auch der Bezeichner des Locks. Bei Deployments, in denen Prozesse der alten und neuen Version parallel laufen, kann dieselbe Verarbeitung dadurch unterschiedliche Locks erhalten. Behandeln Sie dies nicht wie eine bloße Änderung des Anzeigetexts, sondern pflegen Sie Aufgabennamen als stabile, öffentliche Spezifikation.
onOneServer und withoutOverlapping getrennt betrachten
onOneServer()wählt den Server aus, der die Ausführung zu diesem Zeitpunkt übernimmt. Der untersuchteCacheSchedulingMutexhängt Stunde und Minute an den Mutex-Namen des Events an und hält ihn eine Stunde lang. Das ist etwas anderes als ein Überlappungs-Lock, der mit dem Ende der Aufgabe freigegeben wird.withoutOverlapping()verhindert Überschneidungen, solange die vorherige Ausführung noch läuft. Die angegebene Ablaufzeit wird in Minuten angegeben, standardmäßig 1.440 Minuten. Ist sie zu kurz, verfällt der Lock, bevor die Verarbeitung endet.- Stellt
job()den Job in eine Queue, bedeutet der Abschluss des Schedule-Events nicht, dass der Job abgearbeitet ist. Die Duplikatkontrolle auf dem Worker gestalten Sie separat, etwa mit Unique Jobs oder der MiddlewareWithoutOverlappingauf Seiten des Jobs.
onOneServer() aktivieren, nennen Sie als Voraussetzung einen gemeinsam genutzten Cache mit database, memcached, dynamodb oder redis, wie es die offizielle Dokumentation vorgibt. Locks garantieren keine Exactly-once-Ausführung der Geschäftslogik; die Verarbeitung muss auch bei erneuter Ausführung konsistent bleiben.
Schwere Abhängigkeiten zur Laufzeit auflösen
DasLoggerInterface des obigen Heartbeats löst CallbackEvent bei der Ausführung des Events über call() des Containers auf. Bei der Registrierung des Hooks wird weder geloggt noch ein Client erzeugt.
Externe Verbindungen oder Geschäftslogik aus dem Konstruktor herauszuhalten, ist auch bei Artisan-Befehle in Paketen registrieren und Abhängigkeiten auflösen wichtig.
Da
call() und job() CallbackEvents erzeugen, steht runInBackground() nicht zur Verfügung. Langwierige Verarbeitung delegieren Sie an eine Queue oder nutzen bei Bedarf die Hintergrundausführung von command().
Anwendungsweite Einstellungen nicht an sich reißen
Schedule::useCache() ändert den Store des Mutex-Objekts, das der Schedule hält. Diese Einstellung gilt nicht nur für die Events des Pakets, sondern betrifft auch alle anderen Events, die denselben Mutex teilen. Rufen Sie sie nicht bedingungslos im boot() des Pakets auf, sondern behandeln Sie sie als Einstellung, die die nutzende Anwendung wählt.
Ebenso sollte ein Paket Schedule::alwaysOnOneServer(), das Pausieren des Schedulers oder das Ausführungsverhalten im Wartungsmodus nicht eigenmächtig ändern.
Nach Konfigurationsänderungen einen neuen Schedule erzeugen
enabled, Cron-Ausdruck und Zeitzone im Beispiel sind Einstellungen zum Zeitpunkt der Registrierung. Ändern Sie lediglich den Wert von config() für einen bereits erzeugten Schedule, werden weder Events hinzugefügt oder entfernt noch die Konfiguration neu eingelesen. Auch die WeakMap-Prüfung dient nicht der Neukonfiguration.
Bei Deployments mit Konfigurations-Cache bauen Sie den Cache neu auf und prüfen schedule:list in einem Prozess, der die neue Konfiguration lädt. Stellen Sie auch für lang laufende Scheduler und für schedule:run mit laufenden Aufgaben unter einer Minute sicher, dass kein alter Code und keine alte Konfiguration zurückbleiben. Zum Unterbrechen von Sub-Minuten-Aufgaben beim Deployment siehe Task-Scheduling.
Registrierung getrennt von der Ausführung testen
Das folgende Beispieltests/CourierScheduleTest.php nutzt das Composer-Autoloading des Pakets und PHPUnit. Die Mutexe werden durch Test-Doubles ersetzt, sodass das Registrierungsergebnis ohne externen Cache und ohne echtes cron geprüft wird.
Führen Sie nicht alle Aufgaben der nutzenden Anwendung mit
schedule:run aus, nur um den Registrierungstest zu bestehen. Indem Sie Tests des Aufgabenrumpfs und Scheduler-Integrationstests in einer kontrollierten Umgebung trennen, vermeiden Sie Nebenwirkungen unbeteiligter geplanter Aufgaben.
Verwandte Seiten
Task-Scheduling
Ausführungsfrequenz, Einrichtung von cron, Delegation an Queues und Betrieb beim Deployment.
Hooks nach der Service-Auflösung in Paketen
Anwendung auf noch nicht aufgelöste und bereits aufgelöste Services sowie Hinweise zur erneuten Registrierung.
Herangezogene Primärquellen
- Offizielle Laravel-Dokumentation: Task-Scheduling
- Offizielle Laravel-Dokumentation: Paketentwicklung
- FoundationServiceProvider: Registrierung von Schedule als Singleton
- Console Kernel: Erzeugung von Schedule und Standardeinstellungen
- ServiceProvider: callAfterResolving()
- Schedule: Hinzufügen von Events, verzögerte Erzeugung von Jobs, gemeinsamer Mutex
- Event: Mutex-Namen von Befehls-Events
- CallbackEvent: Pflicht zum Namen und Auflösung von Abhängigkeiten zur Laufzeit
- CacheEventMutex: Überlappungs-Lock und Umrechnung der Ablaufzeit
- CacheSchedulingMutex: Lock pro Ausführungszeitpunkt
- Offizielle Tests: Registrierung von Events und Zeitzonen
- Offizielle Tests: Verzögerte Erzeugung über den Job-Klassennamen