Skip to content

Scheduler

Der Scheduler ermöglicht, Tasks oder Commands automatisiert in bestimmten Intervallen auszuführen. Hierfür wird pro Projekt lediglich ein einziger Cronjob auf dem Server benötigt, der minütlich den Scheduler aufruft, welcher daraufhin die auszuführenden Tasks und Commands ermittelt.

Die Intervalle werden also nicht in der crontab-Datei, sondern im Code fest­gelegt. Das hat den Vorteil, dass diese Informationen in der Versionsverwaltung gespeichert sind und das Projekt leichter auf einen anderen Server umgezogen werden kann.

Vorbereitung

Um den Scheduler zu aktivieren, muss folgender Eintrag in der crontab-Datei ergänzt werden. Dabei wird der absolute Pfad zur cmd-Datei des Projekts eingetragen.

* * * * * php /srv/www/.../project/cmd scheduler:run

Intervalle definieren

Welche Tasks und Commands durch den Scheduler ausgeführt werden sollen, wird in der Methode initScheduler der Klasse App\Boot\App definiert.

php
public static function initScheduler(): void
{
    Scheduler::add(new ExampleTask())->daily()->at(3);
}

Mit der Methode Scheduler::add(Task|Command $task) wird dem Scheduler ein neuer Task oder Command hinzugefügt. Die Methode gibt eine Instanz der Klasse Schedule zurück, die über viele Methoden verfügt, um diverse Intervalle zu definieren.

Allgemeine Intervalle

Üblicherweise wird zunächst eine dieser Methoden verwendet, um ein allgemeines Intervall festzulegen. Dieses kann mit den Methoden der nachfolgenden Abschnitte konkretisiert und eingeschränkt werden.

MethodeBeschreibungentspricht Cron
everyMinute()minütlich* * * * *
everyMinutes(int $x)alle $x Minuten*/$x * * * *
everyHour()stündlich (zur vollen Stunde)0 * * * *
everyHours(int $x)alle $x Stunden0 */$x * * *
daily()täglich um 00:000 0 * * *
weekly()wöchentlich montags um 00:000 0 * * 1
monthly()monatlich am 01. um 00:000 0 1 * *
yearly()jährlich am 01.01. um 00:000 0 1 1 *
cron(string $rules)Cron-Ausdruck$rules

Die Methode cron(string $rules) erwartet einen vollständigen Cron-Ausdruck der Form * * * * * (Minute, Stunde, Tag des Monats, Monat, Tag der Woche). Sie dient nur dazu, alte Einträge der crontab-Datei schnell in das Framework kopieren zu können. Durch die anderen Methoden wird der Code lesbarer und verständlicher.

Einzelne Regeln

Mit den folgenden Methoden können einzelne Regeln gesetzt werden, wobei der vorherige Wert der jeweiligen Regel überschrieben wird. Diesen Methoden können Zahlen aus dem gültigen Wertebereich übergeben werden, aber auch Strings in Cron-Syntax, z.B. 15,45, */5 oder 0-30/5.

MethodeBeschreibungWertebereich
setMinute(string $rule)Minute0 - 59
setHour(string $rule)Stunde0 - 23
setDayOfWeek(string $rule)Tag der Woche0 - 7*
setDay(string $rule)Tag des Monats1 - 31
setMonth(string $rule)Monat1 - 12
setYear(string $rule)Jahr0 - 9999

*Da es unterschiedliche Ansichten gibt, ob die Woche montags oder sonntags beginnt, werden für den Sonntag die Werte 0 und 7 zugelassen.

Hilfsmethoden

Folgende Methoden erleichtern die Nutzung der Methoden für einzelne Regeln, indem sie bestimmte Regeln kombinieren oder durch konkrete Namen intuitiver machen.

Methodeentspricht
at(string $hour, string $minute = '0')setHour($hour)->setMinute($minute)
on(string $month, string $day)setMonth($month)->setDay($day)
onMondays()setDayOfWeek('1')
onTuesdays()setDayOfWeek('2')
onWednesdays()setDayOfWeek('3')
onThursdays()setDayOfWeek('4')
onFridays()setDayOfWeek('5')
onSaturdays()setDayOfWeek('6')
onSundays()setDayOfWeek('7')
onWeekdays()setDayOfWeek('1-5')
onWeekends()setDayOfWeek('6,7')

Einschränkungen

Mit diesen Methoden kann die Ausführung eines Tasks oder Commands weiter eingeschränkt werden. Die jeweiligen Bedingungen müssen also zusätzlich zu den zeitlichen Regeln erfüllt sein.

MethodeBeschreibung
between(string $start, string $end)noch nicht implementiert
timezone(string $zone)noch nicht implementiert
environments(string $envs)noch nicht implementiert
if(Closure $cb)noch nicht implementiert

Ablaufsteuerung

MethodeBeschreibung
inBackground()siehe Parallelisierung

Beispiele

Einige Beispiele sollen die Nutzung der oben beschriebenen Methoden verdeutlichen.

php
public static function initScheduler(): void
{
    // alle 5 Minuten
    Scheduler::add(new ExampleTask())->everyMinutes(5);
    
    // stündlich um viertel vor und viertel nach
    Scheduler::add(new ExampleTask())->everyHour()->setMinute('15,45');
    
    // alle 3 Stunden um viertel nach
    Scheduler::add(new ExampleTask())->everyHours(3)->setMinute(15);
    
    // täglich um 03:30
    Scheduler::add(new ExampleTask())->daily()->at(3, 30);
    
    // täglich um 00:15, 00:45, 12:15 und 12:45
    Scheduler::add(new ExampleTask())->daily()->at('0,12', '15,45');
    
    // monatlich am 01. und 15. um 06:00
    Scheduler::add(new ExampleTask())->monthly()->setDay('1,15')->at(6);
    
    // jährlich am 24.12. um 18:00
    Scheduler::add(new ExampleTask())->yearly()->on(12, 24)->at(18);
}

Parallelisierung

Standardmäßig führt der Scheduler alle anstehenden Tasks sequentiell aus, entsprechend der Reihenfolge in der Methode initScheduler. Falls ein Task ungewöhnlich lange braucht kann es also vorkommen, dass folgende Tasks verzögert oder aufgrund von Zeitüber­schreitung gar nicht ausgeführt werden.

Um dieses Problem zu umgehen, kann der Scheduler durch die Methode inBackground angewiesen werden, Tasks parallel im Hintergrund auszuführen. In diesem Fall ruft der Scheduler den Command task:exec auf, sodass jeder Hintergrund-Task in einem eigenen PHP-Prozess läuft.

php
public static function initScheduler(): void
{
    Scheduler::add(new ExampleTask())->everyHour()->inBackground();
}