Auf Perlmonks.com steht die Welt Kopf: Dort stürzen sich hochkarätige Perl-Hacker selbst auf simple Anfängerfragen, weil die Community Punkte für die besten Antworten vergibt. Mit wachsender Punktzahl steigen die Ratgebenden vom Messdiener (Acolyte) über Mönch (Monk) und Papst (Pontiff) schließlich zum Heiligen (Saint) auf. Das System funktioniert seit Jahren, Perlmonks.com ist eines der besten Beispiele für eine funktionierende Internet-Community.
Punktbester
Erfahrungsgemäß erhält die meisten Punkte, wer eine Frage als Erster richtig beantwortet. Statt nun die Seite mit den neuesten Fragen selbst immer wieder aufzurufen, liegt es nahe, ein Skript damit zu beauftragen, das seinen Auftraggeber benachrichtigt, sobald es auf Neues stößt (Abbildung 1).
Der hier vorgestellte Pmwatcher.pl tut genau dies: Das Skript fragt in regelmäßigen Abständen die Seite mit »Newest Nodes« auf Perlmonks.com nach Einträgen ab und merkt sich alte Hüte. Bei neuen Postings sendet es sofort eine Kurznachricht als Instant Message.
Die Implementierung stellt einiges auf den Kopf. Das Skript beauftragt nicht etwa einen externen IM-Client mit der Nachrichtenübermittlung, sondern fungiert selbst als Plugin eines solchen Messengers. Gaim, die Mutter-Applikation ruft es regelmäßig auf. Das Plugin holt daraufhin die neuesten Postings und verschickt über interne Schnittstellen Messages an den Benutzer (Abbildung 2).
Wer bremst, verliert
Doch darf ein Gaim-Plugin keine Zeit vertrödeln: Während es vor sich hin werkelt, kann die Gaim-Applikation keine Events mehr bearbeiten und ihr schönes GUI friert ein. Also muss das Plugin die Kontrolle sofort wieder zurückgeben. Den Inhalt einer Website vom Netz holen dauert unter Umständen aber einige Sekunden. Daher sollten alle I/O-Aktionen im Plugin asynchron erfolgen, sowohl die DNS-Auflösung als auch das Einholen der geforderten Webseite.
Statt all dies neu zu programmieren, bietet es sich an, ein bewährtes Multitasking-Framework wie POE zu verwenden. Wie schon einmal in [3] besprochen, läuft unter POE nur ein einziger Prozess. Kooperatives Multitasking zwischen konkurrierenden Aufgaben sorgt dafür, dass jede ihre Zeitscheibe bekommt.
POE nimmt die Dinge gerne selbst in die Hand und lässt normalerweise seine eigene Event-Schleife laufen. Es ist aber auch in andere Event-Schleifen wie die von GTK oder Perl/Tk integrierbar. Auch für eher ungewöhnliche Szenarien wie die einer Plugin-Architektur findet sich eine Lösung: In der von Gaim aufgerufen Plugin-Prozedur »plugin_load()« definiert das Plugin-Skript Pmwatcher.pl die verschiedenen Tasks, die es später ablaufen lässt.
Bevor »plugin_load()« die Kontrolle an Gaim zurückreicht, ruft es »Gaim::timeout_add($plugin, $UPDATE, &refresh);« auf, was garantiert, dass Gaim nach Ablauf von »$UPDATE« Sekunden wieder die Plugin-Funktion »refresh()« startet. Dort springt POE kurz an, erledigt dringende Aufgaben und gibt die Kontrolle an Gaim zurück.