Batch-Jobs
Über Batch-Jobs kannst du Aufgaben ohne manuellen Aufruf wiederholt ausführen. Batch-Jobs können von Crontabs aufgerufen werden.
Batch-Job registrieren
Du kannst jede Klasse als Batch-Job verwenden, die als "lookupable" gekennzeichnet ist. Wir erstellen im folgenden Beispiel einen Batch-Job im Package atusch\batch
:
<?php namespace atusch\batch; use n2n\context\Lookupable; class ExampleBatchJob implements Lookupable { public function _onNewHour() { echo 'one hour passed'; } }
In Batch-Job-Klassen kannst du bestimmte Callback-Methoden implementieren, die je nach Namen mit einer anderen Frequenz ausgeführt werden. Im oben stehenden Beispiel wird die Methode _onNewHour()
einmal pro Stunde ausgeführt.
Batch-Jobs müssen im app.ini
unter der Gruppe [general]
registriert werden.
[general] application.batch_jobs[] = "atusch\batch\ExampleBatchJob"
Batch-Jobs einrichten
In einer Standard-n2n-Installation findest du im Skript public/index.php
die Anweisung n2n\N2N::autoInvokeBatchJobs();
. Über diese Anweisung werden deine Batch-Jobs angestossen, d. h. es werden alle Callback-Methoden ausgeführt, die zum aktuellen Zeitpunkt ausführungsberechtigt sind. Belässt du n2n\N2N::autoInvokeBatchJobs();
in public/index.php
, bedeutet dies, dass während jedem Seitenaufruf auch Batch-Jobs ausgeführt werden könnten (public/index.php
wird bei jedem Seitenaufruf ausgeführt). Dauert dein Batch-Job etwas länger, müssen deine Nutzer von Zeit zu Zeit bei einem Seitenaufruf auch eine entsprechend längere Request-Zeit in Kauf nehmen.
Ausserdem machst du die Frequenz, mit der deine Batch-Jobs aufgerufen werden, vom Benutzerverhalten abhängig. Hast du, wie im oben stehenden Beispiel, einen Batch-Job mit einer _onNewHour()
-Methode registriert und für 3 Stunden keine Seitenaufrufe von Nutzern, so wird diese Methode in diesen 3 Stunden auch nie ausgeführt, da in dieser Zeit n2n\N2N::autoInvokeBatchJobs();
nie aufgerufen wurde.
Um deine Batch-Jobs etwas berechenbarer zu machen, lohnt es sich n2n\N2N::autoInvokeBatchJobs();
in ein separates Skript auszulagern (z. B. batch.php
). Dieses Skript könnte folgendermassen aussehen:
<?php $pubPath = realpath(dirname(__FILE__)); $appPath = realpath($pubPath . '/../app'); $n2nPath = realpath($pubPath . '/../lib'); $varPath = realpath($pubPath . '/../var'); set_include_path(implode(PATH_SEPARATOR, array($appPath, $n2nPath, get_include_path()))); if (isset($_SERVER['N2N_STAGE'])) { define('N2N_STAGE', $_SERVER['N2N_STAGE']); } require_once 'n2n/N2N.php'; n2n\N2N::setup($pubPath, $varPath); n2n\N2N::initialize(new n2n\core\FileN2nCache()); n2n\N2N::autoInvokeBatchJobs(); n2n\N2N::finalize();
Nun kannst du einen Crontab aufsetzen, der dieses Skript beliebig oft aufruft. Natürlich musst du auch hier eine geeignete Frequenz wählen. Hast du einen Batch-Job mit Callback-Methode _onNewHour()
registriert, muss das Skript auch mindestens einmal pro Stunde aufgerufen werden, um sicher zu gehen, dass _onNewHour()
auch wirklich jede Stunde ausgeführt wird.
Möchtest du, dass deine Batch-Jobs in einem Http-Context aufgerufen werden, eignet sich wget
als Crontab-Anweisung.
wget -O /dev/null http://www.example.com/batch.php
n2n\N2N::autoInvokeBatchJobs();
aus public/index.php
zu löschen, falls du ein separates Batch-Skript eingerichtet hast.var\tmp\n2n\appcache\n2n.batch.TriggerTracker
gespeichert. Möchtest du das Ausführen aller Batch-Jobs erzwingen, kannst du dieses Verzeichnis einfach löschen. Sobald der nächste Batch-Job ausgeführt wird, wird es neu erstellt.Callback-Methoden
Alle Callback-Methoden in Batch-Jobs sind magisch und können eine beliebige Sichtbarkeit haben. Wird der Batch-Job manuell oder vom System angestossen, so wird immer zuerst die _onTrigger()
Callback-Methode ausgeführt. Indem du einen Parameter mit Typ DateTime
definierst, kannst du dir ausserdem den Zeitpunkt übergeben lassen, an dem die entsprechende Methode das letzte Mal ausgeführt wurde.
Folgende Methoden werden mit einer vordefinierten Frequenz aufgerufen:
<?php namespace atusch\batch; use n2n\model\Lookupable; class ExampleBatchJob implements Lookupable { public function _onTrigger() { // gets called every time the batch job is triggered } public function _onNewHour(\DateTime $lastTriggered) { // gets called on every new hour } public function _onNewDay() { // gets called on every new day } public function _onNewWeek() { // gets called on every new week } public function _onNewMonth() { // gets called on every new month } public function _onNewYear() { // gets called on every new year } }
Alle Callback-Methoden mit Prefex "_onNew" werden ausgeführt, sobald sich die entsprechende Zeiteinheit des akutellen Zeitpunkts gegenüber dem Zeitpunkt unterscheidet, an dem die Callback-Methode das letzte Mal ausgeführt wurde. Wird _onNewHour()
zum Beispiel um 16:45 Uhr ausgeführt, kann sie also bereits um 17:00 Uhr wieder ausgeführt werden, da sich die Zeiteinheit "Hour" geändert hat.
Über die Annotation n2n\batch\AnnoBatch
kannst du auch eigene Callback-Methoden bestimmen. n2n\batch\AnnoBatch
erwartet als Parameter ein \DateInterval
, das der Frequenz entspricht, mit welcher deine Callback-Methode aufgerufen werden soll.
<?php namespace atusch\batch; use n2n\model\Lookupable; use n2n\batch\AnnoBatch; class ExampleBatchJob implements Lookupable { private static function _annos(AnnoInit $ai) { $ai->m('every15Min', new AnnoBatch(new \DateInterval('PT15M'))); } public function every15Min() { // gets called every 15 minutes } }
Im oben stehenden Beispiel wird die Methode every15Min()
alle 15 Minuten ausgeführt.