Open Source im professionellen Einsatz
Linux-Magazin 12/2014
© innovari, Fotolia

© innovari, Fotolia

So verwaltet der Perl-Programmierer asynchrone Programmflüsse effizient

Pyramide der Verdammnis

Asynchroner Programmfluss artet schnell in unleserlichen Code aus, falls kein übergreifendes Konzept die Struktur vorgibt. Zum Glück hat die Javascript-Gemeinde einige funktionale Tricks erfunden, die auch dabei helfen, asynchronen Perl-Code zu zähmen.

504

Online PLUS

In einem Screencast demonstriert Michael Schilli das Beispiel: http://www.linux-magazin.de/2014/12/plus

Sogar Experten bauen in ihren Code nicht selten unbeabsichtigt Wettlaufsituationen (Race Conditions) ein. Leicht übersehen selbst sie Seiteneffekte, wenn Multithreading im Code plötzlich dazwischenfunkt. Die Ursachen müssen Spürtrupps später mit viel Aufwand erkunden (Abbildung 1). Denn der Fehler, den der Kunde meldet, kommt nur sporadisch vor, weil er nur beim zeitlichen Zusammentreffen bestimmter Ereignisse auftritt und sich in der Entwicklungsabteilung nicht einfach reproduzieren lässt.

© © Sergey Nivens, 123RFAbbildung 1: Asynchroner Programmfluss sorgt nicht selten für unleserlichen Code.

Ein Thread reicht

Läuft – wie etwa in einer Javascript-Anwendung – nur ein Thread, dann gibt es keine Race Conditions, denn die CPU arbeitet den Code wie aufgeschrieben ab, nichts kommt unerwartet dazwischen. So weit also ein klares Plus.

Doch damit ein Programm mit nur einem Thread ebenso schnell läuft wie eines mit vielen, darf es nicht untätig herumsitzen, während zum Beispiel eine sehr viel langsamere Netzwerkoperation läuft. Dafür gibt der Programmierer die Kontrolle in ausgewählten Programmteilen an eine Eventschleife ab, die Ereignisse dann asynchron abarbeitet. Ist das Programmierergehirn einmal auf den asynchronen Programmfluss umgestellt, schreiben sich auch komplizierte Abläufe wunderbar leicht. Aber bis es so weit ist, sind einige Hürden zu nehmen.

Hipster, hilf!

Manch einer kämpft lange damit, asynchrone Programmflüsse zu begreifen. Die Auferstehung von Javascript als Hipstersprache, besonders auf Server-Seite mit dem komplett asynchronen Framework Node.js, brachte nicht nur einige der altbekannten typischen Stolpersteine zutage. Vielmehr entstanden in letzter Zeit einige elegante Lösungen wie Pubsub, Promises oder ganze Frameworks wie Async.js, die den asynchronen Fluss auch komplexer Applikationen bändigen helfen [2].

Asynchronen Fluss empfinden Neulinge auch in Perl oft als Einschränkung, denn auf einmal können sie zum Beispiel den Inhalt einer Webseite nicht mehr einfach mit dem CPAN-Modul LWP::User-Agent und dem Aufruf

$ua->get("http://foo.com");

einholen. Während »get()« auf die Antwort des Webservers und die zäh eintrudelnden Daten wartet, stünden dann nämlich alle Räder der Applikation still. So geht es also nicht. Vielmehr läuft nun alles über Callbacks, wie im Any-Event-Framework etwa mit:

http_get("http://foo.com", sub { print $_[1] } );

Das Programm gibt dabei nur den Auftrag, die Webseite abzuholen, und kehrt sofort nach dem Aufruf der Funktion »http_get()« zum Hauptprogramm zurück. Die Eventschleife hat den Auftrag angenommen und kümmert sich ums Einholen und Aufsammeln der Daten erst dann, wenn das Programm wieder eine Pause einlegt. Falls alles komplett vorliegt, ruft die globale Eventschleife den zuvor beigefügten Callback mit den eingeholten Daten auf, der sie mit der »print« -Anweisung ausgibt.

Diese Struktur wirft den Programmfluss einer Applikation allerdings gehörig über den Haufen. Stehen zum Beispiel mehrere Webrequests hintereinander an, deren Anfragen vorher abgefragte Ergebnisse benötigen, nimmt die Verschachtelung schnell schwer zu durchschauende Ausmaße an:

http_get($url1,
   sub {
      http_get($url2, sub {
         # ...
      });
 });

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Perl-Snapshot

    Damit ein Anwender schnell über womöglich ungewollte Zu- und Abgänge in seinem Netzwerk informiert wird, speichert ein Perl-Daemon periodisch die Daten von Nmap-Scans und gibt sie über ein eingebautes Webinterface an Nagios weiter.

  • Screencast zum Perl-Snapshot 12/2014

    Diesmal geht es um asynchrone Programmflüsse und ihr Management in Perl.

  • Perl-Snapshot

    HTML 5 bringt Websockets, über die Webserver mit ihren Clients in einen Dialog treten können. Die im Folgenden vorgestellte kleine Webapplikation zeigt in Echtzeit im Browser, welche Seiten beliebige User von einem Webserver im Moment aufrufen.

  • Jquery 3.0 gibt es auch in schlank

    Seit gestern ist Jquery in Version 3.0.0 erhältlich. Für Entwickler gibt es mit dem Slim Build eine besonders schlanke Variante, zudem unterstützt Jquery 3.0 Promises/A+ und ES2015-Promises.

  • Tierische Kurssprünge

    Ein in Perl geschriebenes Pidgin-Plugin ignoriert dröge Börsentage, an denen die Kurse stillstehen, aber schlägt per Instant Message Alarm, falls die Aktien anfangen Achterbahn zu fahren.

comments powered by Disqus

Ausgabe 04/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.