Das heißt, man tun gut daran, selbst einen Timeout zu implementieren. Das ist zum Glück sehr einfach. Es gilt nur zu beachten, dass man »AE::now_update
«
vor dem Erzeugen der Condition-Variable aufruft. Den Watcher für den Timeout erzeugt Zeile 34.
Wie in [1] erläutert, müssen die Signale TERM und INT von der Aktivierung der Signal-Handler in den Zeilen 44 bis 46 bis zum Ende der »execute
«
-Anweisung blockiert werden, um eine Race-Condition zu vermeiden. Nun kann es aber passieren, dass »execute
«
mit einer Exception abgebrochen wird, um die man sich normalerweise nicht weiter kümmern müsste, weil Mod-Perl daraus automatisch eine Antwort mit dem HTTP-Code 500 (SERVER ERROR) macht. Die Signalmaske des Prozesses ist jedoch eine globale Eigenschaft, die zurückgesetzt werden muss. Sonst stockt der Webserver beim Herunterfahren.
Für solche Fälle ist das Guard-Modul hilfreich. In Zeile 40 speichert die Variable »$guard
«
ein Objekt, bei dessen Zerstörung der übergebene Code-Block ausgeführt und damit die Signalmaske zurückgesetzt wird. In Zeile 48 passiert das explizit als Teil des Programms. Wenn jedoch der Execute-Aufruf abbricht, wird dieser Code nicht ausgeführt. Die »$guard-
«
Variable wird von Perl aber automatisch zerstört. Als Nebeneffekt wird die Signalmaske wiederhergestellt.
Jetzt, nachdem das Gerüst steht, können Aktionen eingefügt werden. Im Moment kennt die Anwendung nur »test
«
. Zudem ist sie eigentlich nur ein Platzhalter und hat mit der Anwendung nichts zu tun. Zum Testen des Gerüsts eignet sie sich aber gut.
Doch als erstes muss das Modul noch in der »httpd.conf
«
eingebunden werden. Neben der »LoadModule
«
-Anweisung, um Mod-Perl zu laden, ist dazu Folgendes nötig:
PerlModule Chat <Location /Chat> SetHandler modperl PerlResponseHandler Chat </Location>
Außerdem muss das Chat-Modul im Perl-Suchpfad gefunden werden (siehe auch Kasten "Mod-Perl – eine Einführung").
Mod-Perl – eine Einführung
Mod-Perl ist ein in den Apache-HTTPD eingebetteter Perl-Interpreter. Im Gegensatz zu mit Mod-CGI eingebundenen Skripten wird der Interpreter also nicht für jede Anfrage neu gestartet. Im Unterschied zu Techniken wie FastCGI oder Tomcat gibt es bei Mod-Perl kein Backend, dem die Anfrage vom Webserver übermittelt wird. Der Perl-Interpreter läuft im selben Prozess.
Das Perl-Programm hat daher direkten Zugriff auf alle Ressourcen des Webservers, also auch auf die TCP-Verbindung zum Browser. Es gibt mehrere Wege, einer Anfrage eigenen Perl-Code zuzuordnen. Die direkteste ist der sogenannte »PerlResponseHandler
«
. Dazu schreibt man ein gewöhnliches Perl-Modul und implementiert darin eine Funktion mit dem Namen »handler
«
. Diese Funktion wird dann vom Webserver mit einem Parameter aufgerufen, der die Anfrage repräsentiert.
Ein einfaches Hello-World sieht wie folgt aus:
package Hello::World; use Apache2::RequestRec (); use Apache2::RequestIO (); use Apache2::Const -compile=>qw/OK/; sub handler { my ($r)=@_; $r->content_type('text/plain'); $r->print("hello world\n"); return Apache2::Const::OK; } 1;
Das Modul installiert man im Suchpfad von Perl und bindet es in die »httpd.conf
«
ein:
LoadModule perl_module libexec/mod_perl.so PerlModule Hello::World <Location /hello-world> SetHandler modperl PerlResponseHandler Hello::World </Location>
Der Pfad in der LoadModule-Zeile muss eventuell angepasst werden.
Wollen Sie das Modul in einem separaten Suchpfad installieren, so kann dieser dem Perl-Interpreter entweder beim Start des Webservers über die Umgebungsvariable »PERL5LIB
«
oder mittels der Anweisung »PerlSwitches
«
in der »httpd.conf
«
übergeben werden.
Beispiel:
PerlSwitches -I/home/ich/mein/modperl
Nach einem Restart des Webservers kann das Modul zum Beispiel mittels »curl
«
ausprobiert werden:
$ curl http://localhost/hello-world hello world
Mehr Informationen zu Mod-Perl sind unter [2] zu finden.
Die Test-Aktion erwartet zwei Parameter: eine SQL-Anweisung »q
«
und eine Liste mit Bind-Parametern »param
«
. Abbildung 1 zeigt einen solchen Aufruf mit »curl
«
. Die Option »-d
«
erzeugt eine POST-Anfrage und übergibt gleichzeitig den Request-Body. Normale CGI-Skripte erwarten ihre Parameter oft URL-kodiert. Dieses erwartet jedoch JSON. Der Javascript-Teil im Browser wird dadurch einfacher.