Hintergrundprozesse in WordPress erstellen

Wenn ein PHP-Skript ausgeführt wird, dann lädt die Seite normalerweise so lange, bis die Aufgabe ausgeführt ist (oder es einen Fehler gibt). In vielen Fällen ist das auch kein Problem, da das Skript nicht lange läuft. Wenn das Skript aber sehr viele Aufgaben ausführen muss und damit eventuell mehrere Minuten oder sogar Stunden beschäftigt ist, wäre es praktisch sowas im Hintergrund ablaufen zu lassen. Hier zeige ich, wie das mit einer Bibliothek für WordPress umgesetzt werden kann.

Vorteile von der Hintergrundverarbeitung

  • Der Tab muss nicht geöffnet bleiben, bis die Aufgabe erledigt ist.
  • Über passende Tools (eins davon stelle ich gleich vor) kann verhindert werden, dass der Server in ein Timeout läuft.

Nachteile von der Hintergrundverarbeitung

  • Als »Nachteil« habe ich bisher nur festgestellt, dass es nicht so leicht ist den Hintergrundprozess zu beenden, falls es ein Problem damit gibt 🙂

Nutzung von Hintergrundprozessen mit »WP Background Processing«-Bibliothek

Über den Artikel »How to do Background Processing in WordPress Plugins and Themes« von Ashley Rich bin ich auf seine Bibliothek WP Background Processing gekommen, die das Erstellen von Hintergrundaufgaben in WordPress ermöglicht. Standardmäßig werden die Aufgaben in der Datenbank gespeichert, aber in seinem Artikel erwähnt Ashley die Möglichkeit, das auch via Redis oder ähnliches zu speichern.

Die Bibliothek ermöglicht zwei Arten von Abläufen: Async Request für einmalige langsame Aufgaben und Background Process, bei dem mehrere Aufgaben in einer Queue gespeichert und dann abgearbeitet werden. Diese Queues passen sich den verfügbaren Server-Ressourcen an, also werden auf Servern mit mehr Ressourcen mehr Einträge pro Batch verarbeitet als auf schwächeren Servern. Auch wenn die Queue bereits abgearbeitet wird, können neue Einträge eingefügt werden. Ich werde hier ein kurzes Beispiel eines Background Process zeigen – das andere habe ich bisher nicht getestet.

Ihr könnt die Bibliothek über Composer installieren:

composer require a5hleyrich/wp-background-processing

Wie in der Readme auf GitHub beschrieben, müssen wir eine Kindklasse von WP_Background_Process erstellen und darin dann unseren Task anlegen. Unser kleiner (und nicht sehr sinnvoller) Beispiel-Task sieht so aus:

class BackgroundProcess extends WP_Background_Process {

	protected $action = 'florianbrinkmann_background_process';

	/**
	 * Task
	 *
	 * Override this method to perform any actions required on each
	 * queue item. Return the modified item for further processing
	 * in the next pass through. Or, return false to remove the
	 * item from the queue.
	 *
	 * @param mixed $item Queue item to iterate over
	 *
	 * @return mixed
	 */
	protected function task( $item ) {
		error_log( $item );

		sleep( 5 );

		return false;
	}

	/**
	 * Complete
	 *
	 * Override if applicable, but ensure that the below actions are
	 * performed, or, call parent::complete().
	 */
	protected function complete() {
		parent::complete();
	}
}
  • protected $action sollte einen eindeutigen Bezeichner bekommen – darüber sind die Batches des Hintergrundprozesses dann auch in der Datenbank zu finden.
  • protected function task( $item ) ist die Aufgabe, die für jeden Eintrag in der Queue durchlaufen wird – wir schreiben den übergebenen Wert ins Error-Log und unterbrechen die Laufzeit des Skripts für fünf Sekunden. Wenn von task() der Wert false zurückgegeben wird, wird der Eintrag aus der Queue entfernt. Wird der Eintrag zurückgegeben, kann er im nächsten Durchgang weiterverarbeitet werden (das habe ich aber bisher noch nicht getestet).
  • In protected function complete() können Aktionen ausgeführt werden nachdem der Hintergrundprozess erfolgreich abgelaufen ist, etwa eine Erfolgsmeldung via E-Mail verschicken. Wichtig ist, dass parent::complete() ausgeführt wird.

Wenn wir diesen Prozess jetzt starten wollen, können wir wie folgt vorgehen (Voraussetzung ist natürlich, dass unsere Klasse zugänglich ist):

$background_process = new BackgroundProcessExample();

// Add items to the queue.
$counter = 0;
do {
	$counter ++;
	$background_process->push_to_queue( $counter );
} while ( $counter < 10 );

// Start the queue.
$background_process->save()->dispatch();

Zunächst speichern wir in $background_process ein Objekt unserer BackgroundProcessExample()-Klasse und durchlaufen anschließend eine Schleife, in der wir eine Zählervariable erhöhen. Über $background_process->push_to_queue( $counter ); speichern wir den aktuellen Wert der Zählervariable als Eintrag in der Queue und starten nach Beendigung der Schleife das Abarbeiten der Queue über $background_process->save()->dispatch();.

Wenn ihr das Skript ausführt und danach in euer Error-Log schaut (nicht sofort, da bei jedem Eintrag ja fünf Sekunden Verzögerung eingebaut sind), solltet ihr die Zahlen 1 bis 10 in einem Abstand von ungefähr fünf Sekunden aufgelistet sehen. Das Laden der Seite beim Skriptaufruf hat aber hoffentlich keine 50 Sekunden gedauert, der Prozess ist also im Hintergrund abgelaufen.

Nach demselben Prinzip können jetzt sinnvollere Aufgaben in den Hintergrund ausgelagert werden, beispielsweise die programmatische Bearbeitung einer großen Menge Beiträge oder ähnliches.

Das könnte auch interessant sein

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.