Stapelverarbeitung mit PHP


Heute mal ein Klassiker der Computerei: Batchjobs. Man knallt einem Programm einen Stapel voll Aufträge vor die Nase und die müssen abgearbeitet werden.  Die Jobs sollen in einem Webinterface vergeben werden und dann von einem anderen Programm weiterverarbeitet werden.

Die Grundlage für dieses Projekt ist der Stapelspeicher oder Stack. Der kennt in seiner klassischen Form drei Funktionen: Push, Pop und Peek.

Push legt etwas auf dem Stapel ab, Pop nimmt es herunter. Mit Peek kann man sich das oberste Element anschauen, ohne es zu entfernen.

Meinen Stapel halte ich mit einer Textdatei persistent.  Noch einfacher geht es nicht. Die Methode Pop nimmt bei meinem Stack das unterste Element vom Stapel.

Der Stapel wird in einer Klasse mit diesem Rumpf implementiert:

Die Klasse wird wie der Name schon sagt die Grundlage für meine Stapelverarbeitung sein.

Nun werden 2 Skripte benötigt. Ein Skript (Sklaventreiber) legt Aufträge auf den Stapel und das andere (Sklave) arbeitet den Stapel ab. Der Sklave könnte im inneren so aussehen:

#!/usr/bin/php

<?php

$stack = new Stack(‘joblist’);
$job=$stack->peek();

echo „$job wird verarbeitet\n“;

sleep(60); //ist ja nicht wirklich was zu tun da
echo „fertig“;

$stack->pop();

?>


Der Sklaventreiber ist einfach zu implementieren. Es muß ja nur pushjob() aufgerufen werden.  Man kann auch selbst zum Sklaventreiber werden indem man eine neue Zeile in die Jobliste einfügt:).Für meine Stapelverarbeitung ist es wichtig, daß immer nur ein Sklave am arbeiten ist.  Wenn der Sklave gestartet wird, muß er vor Arbeitsbeginn prüfen, ob er auch wirklich alleine ist.  Bei meinem Linux ist der wunderbare Befehl pgrep dabei. Das Programm findet heraus, ob ein Programm gestartet ist und gibt die Prozess Id(s) zurück.

Diese Prüfung realisiere ich mit slaveRunning():

if (!$stack->slaveRunnig()){

$job=$stack->peek();
if ($stack->count()>0){

while ($stack->count()>0){

echo „$job wird verarbeitet\n“;

sleep(15);

$stack->pop();

}

}else {

echo „Jobliste leer\n“;

}

} else {

echo „da is schon wer am arbeiten\n“;

}echo „fertig\n“;

Die Methode habe ich nicht in die Klasse Stack gepackt, sondern einfach eine neue Klasse namens „Batch“ geschrieben die von Stack erbt. Leider kann Eclipse das nicht anzeigen:(:

Wenn man nun seine Crontab um einen Eintrag für dieses Skript ergänzt läuft die Geschichte automatisch ab. Ich habe das mal für den Interessierten bei Github eingecheckt.

Advertisements
Dieser Beitrag wurde unter php abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s