ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2009/anyevent.pod
Revision: 1.3
Committed: Fri Jan 16 05:13:36 2009 UTC (17 years, 8 months ago) by root
Branch: MAIN
Changes since 1.2: +40 -37 lines
Log Message:
valerienfixes

File Contents

# User Rev Content
1 root 1.1 =encoding utf-8
2    
3     =head1 AnyEvent - Eine Welt ohne Religion
4    
5     In diesem Vortrag möchte ich die neuesten Entwicklungen in Sachen
6     AnyEvent vorstellen (asynchrones IPv4/IPv6, asynchrones DNS, TLS uvm.), sowie
7     einige Hintergrundinformationen zu bestehenden Event-Modulen auf CPAN,
8     sowie Benchmarks, vorstellen.
9    
10     Doch zuerst: der Titel klingt sicherlich etwas seltsam - was bedeutet er?
11    
12 root 1.3 Nun, AnyEvent ist, wie im Namensteil "Event" steht, ein Event-Modul
13 root 1.1 bzw. eine Event-Bibliothek. Event-Module oder -Bibliotheken stellen
14 root 1.3 im allgemeinen Funktionalität bereit, mit der man auf Ereignisse
15 root 1.1 (Events), warten kann, speziell Ereignisse der Art "Zeitpunkt soundso
16     ist erreicht" und "File Descriptor soundso kann jetzt nichtblockierend
17     gelesen/geschrieben werden."
18    
19     Derartige Event-Bibliotheken gibt es zuhauf (Tk, Glib, Event, EV uvm.),
20     doch trotz der offensichtlichen Vorteile Event-basierter Programmierung
21     (z.B. beinahe automatische Parallelisierbarkeit) werden sie kaum in
22     CPAN-Modulen eingesetzt.
23    
24     Meiner Meinung nach liegt der Grund schlicht darin, daß alle diese
25     Event-Bibliotheken exklusiv sind: sie dulden niemanden neben sich. Wie
26     bei den meisten Religionen auch, muss man sich einem dieser Modelle
27     ausliefern. Konkret bedeutet dies für Modul-Autoren: benutzt man
28     z.B. Glib in seinem Modul, muss auch jeder Benutzer dieses Modules Glib
29     benutzen, was natürlich eine starke Einschränkung darstellt, vor allem,
30     wenn das Modul selbst eigentlich nur "irgendwelche" Events benötigt, die
31     im Prinzip jede beliebige Event-Bibliothek liefert.
32    
33     Einige Module auf CPAN haben versucht, aus dieser Not eine Tugend zu
34     machen: POE z.B. kann andere Event-Module als Implementation benutzen (in
35     der Praxis funktioniert das zwar nur mit einigen wenigen, aber die Idee
36     zählt). Lieder verschlimmert dies das Problem nur: POE z.B. verlangt
37     beinahe religiöse Glaubensbekenntnisse und ist kein bisschen kompatibler,
38     im Gegenteil: obwohl POE Backends für Gtk+ und Event besitzt, kann man
39     POE-Module nicht in einem Gtk+ oder Event-basiertem Programm benutzen:
40     setzt man POE in seinem Modul ein, so muss auch jeder Benutzer des Moduls
41     POE benutzen, sowie auch das Hauptprogramm selbst.
42    
43     AnyEvent dagegen ist I<grundsätzlich> anders: Im Stile von anderen
44     C<Any*>-Modulen ist es lediglich eine Schnittstelle zu diesen. Dabei passt
45     es sich an jedes unterstützte Event-Modell an, ohne daß sich die API
46     ändert. Das bedeutet, daß man getrost Module benutzen kann, die AnyEvent
47     benötigen und intern auch benutzen, aber der Benutzer des Moduls sieht
48     davon erstmal nichts und kann jede beliebige Event-Bibliothek benutzen.
49    
50     AnyEvent ist 100% Pure-Perl, und kommt mit eigener, schneller,
51     Event-Bibliothek, so daß auch auf Systemen, wo kein anderes Event-Modell
52 root 1.3 verfügbar ist, eventbasiert programmiert werden kann.
53 root 1.1
54     =head2 AnyEvent am Beispiel AnyEvent::CouchDB
55    
56     Ein gutes Beispiel dafür ist C<AnyEvent::CouchDB>. Außer im Namen,
57     kommt AnyEvent in der API dieses Moduls nicht vor. Eine einfache
58     Datenbankabfrage sieht dementsprechend auch ganz langweilig aus:
59    
60     my $data = $db->view('users/all', { key => 'b' })->recv
61    
62 root 1.3 Obwohl die Abfrage selbst ereignisgesteuert ist, muss man als Benutzer
63 root 1.1 des Moduls kaum darunter leiden, lediglich die Zweiteilung der Aufgabe in
64     "Start-Phase" (C<view>-Methode) und "Resultat-Phase" (C<recv>-Methode) ist
65     typisch. Daß intern AnyEvent werkelt, fällt nicht auf, außer, daß die
66     Abfrage in einem laufenden Tk/Gtk usf.-Programm dieses nicht anhält.
67    
68 root 1.3 Im Code werde die Vorteile sichtbar, wenn man mehrere Abfragen "gleichzeitig"
69 root 1.1 (genauer: miteinander verflochten) ausführt:
70    
71     my @data = map $_->recv,
72     map $db->view ('users/al', { key => $_ }),
73     qw(key1 key2 key3 key4);
74    
75     Auch hierbei muss man nicht darauf achten, welches Event-Modul benutzt
76     wird (oder ob man überhaupt ein spezielles benutzt) - es funktioniert
77     einfach.
78    
79     Richtig Spaß macht es, wenn man realisiert, daß man praktisch alle
80     AnyEvent-benutzenden Module beliebig kombinieren kann, und Aufgaben
81     quasi "im Hintergrund" erledigen kann, z.B. mit C<AnyEvent::CouchDB> und
82     C<AnyEvent::HTTP>:
83    
84     $db->view('users/all', { key => 'b' })->cb (sub {
85     my $data = shift->revc;
86     # daten erhalten
87     });
88    
89     AnyEvent::HTTP::http_get "http://www.porttracker.co.uk", sub {
90     my $html = $_[1];
91     # daten erhalten
92     };
93    
94     # hier kann man weitere Dinge erledigen
95    
96     Und all das kann man in den eigenen Modulen nutzen, ohne sich irgendwie
97     auf ein bestimmtes Event-Modell festzulegen.
98    
99    
100     =head2 AnyEvent - Grundlegendes
101    
102     AnyEvent selbst wurde letztes Jahr an dieser Stelle ausführlich
103     vorgestellt, daher möchte ich hier nur eine kurze Übersicht
104     bzw. Einführung in AnyEvent als rein Event-Bibliothek geben:
105    
106 root 1.3 Wie viele andere Bibliotheken auch, benutzt AnyEvent das Konzept eines
107     "Watchers", eines Objekts, das wie ein Wachhund auf ein bestimmtes
108     Ereignis reagiert (watch/watcher = Wache/Beobachter) und bei Eintreten
109     eine Aktion auslöst, z.B. Aufrufen eines Callbacks.
110 root 1.1
111     Diese Watcher gibt es für die folgenden Ereignistypen:
112    
113     =over 4
114    
115     =item Zeit - timer
116    
117     my $timer = AnyEvent->timer (after => 7, cb => sub {
118     warn "Sieben Sekundne sind abgelaufen!";
119     });
120    
121     Timer können nach einer gewissen Zeit ablaufen, oder wiederholt (z.B.
122     alle 3s) Ereignisse auslösen und Callbacks aufrufen.
123    
124     =item I/O auf File Handles - io
125    
126     my $watcher = AnyEvent->io (fh => *STDIN, poll => 'r', cb => sub {
127     my $line = <STDIN>;
128     # zeile von stdin gelesen
129     });
130    
131     I/O-Watcher beobachten einen File Handle und können einen Callback
132     aufrufen, wenn gelesen oder geschrieben werden kann.
133    
134     =item Signale - signal
135    
136     my $quit = AnyEvent->condvar;
137    
138     my $term = AnyEvent->signal (signal => "TERM", cb => sub {
139     $quit->send;
140     });
141    
142     ...
143    
144     $quit->recv
145    
146     Mit Signal-Watchers kann man synchron auf das Auftreten von Signalen
147     warten.
148    
149 root 1.3 Das obige Beispiel benutzt eine "condition variable", um mit dem
150     Hauptprogramm zu kommunizieren (mehr Info s.u.).
151 root 1.1
152     =item Kindprozesse sterben sehen - child
153    
154     my $w = AnyEvent->child (pid => $pid, cb => sub {
155     warn "pid $pid hat sich beendet\n";
156     });
157    
158     Eher selten benötigt, aber sehr schwer zu implementieren (wenn man es
159 root 1.3 richtig tun möchte :), sind Child-Watcher: mit diesen kann man auf das
160 root 1.1 Beenden von ge-fork-ten Prozessen warten.
161    
162     =back
163    
164     =head3 Wenn man mal nichts tun möchte
165    
166     Event-basierte APIs haben eines gemein: Im allgemeinen werden Vorgänge
167     nur gestartet und laufen dann quasi-parallel im Hintergrund ab.
168    
169     Aber wenn man nun genügend solche Vorgänge gestartet hat, möchte man ja
170     irgendwann auch mal auf die Ergebnisse warten.
171    
172     Dies erledigt entweder das Hauptprogramm, indem es die entsprechenden
173     Funktionen der Event-Bibliothek aufruft (z.B. C<Event::loop> oder C<main
174     Gtk>), oder man benutzt sogenannte "condition variables", mit denen man
175     auf das eintreten eines bestimmten Zustands warten kann.
176    
177     "Condition Variables" sind so etwas wie "Rendezvouspunkte" zwischen dem
178     Erzeuger von Daten oder einem Ereignis (z.B. C<AnyEvent::CouchDB->view>
179     oder C<AnyEvent::HTTP::http_get>, aber auch genauso C<< AnyEvent->timer
180     >>) und dem Konsumenten (der Benutzer dieser Funktionen, der die Daten
181     haben oder einfach auf das Ereignis warten möchte).
182    
183     =head1 Neues!
184    
185     Auf zu neuen Ufern - im letzten Jahr hat sich viel getan, sowohl in
186     AnyEvent selbst, als auch in Sachen "andere Module die AnyEvent benutzen".
187    
188     =head2 Altes!
189    
190     Die wichtigsten Eigenschaften von AnyEvent sind allerdings beim
191     alten geblieben:
192    
193     =over 4
194    
195     =item * Die API hat sich kaum verändert, bzw. ist 100%
196     rückwärtskompatibel.
197    
198     =item * AnyEvent ist nach wie vor "Pure-Perl".
199    
200     =item * Der Event-Teil ist nach wie vor getrennt von den anderen Teilen,
201 root 1.3 das Event-Modul ist klein und wenn man bezahlt nur für das, was man
202 root 1.1 benutzt.
203    
204     =back
205    
206     Aber nun zu den Neuigkeiten:
207    
208    
209     =head2 AnyEvent::Strict
210    
211     Aus Geschwindigkeitsgründen macht AnyEvent selbst keine
212     Parameterprüfung, ganz einfach deshalb, weil die Prüfung meistens mehr
213     Zeit in Anspruch nimmt als der Rest der Funktion.
214    
215     Für einen erfahrenen AnyEvent-Benutzer ist das in der Praxis kein
216     Problem, aber wenn man die API noch nicht genau kennt, können sich so
217     Fehler einschleichen (z.B. alte Event-Hasen benutzen gerne C<fd> statt
218     C<fh> um einen I/O-Watcher zu erzeugen).
219    
220     Daher bietet AnyEvent optional eine strenge Prüfung aller
221     Parameter an. Die kann man ganz einfach aktivieren, in dem man die
222     Environment-Variable C<PERL_ANYEVENT_STRICT> auf C<1> setzt, was auf allen
223     meinen Entwicklungsrechnern der Fall ist.
224    
225     Falls man diese Prüfung grundsätzlich wünscht (was ich ganz dringend
226     I<nicht> empfehle, siehe aber den Punkt "keine Religion"...), kann man diese
227     auch immer aktivieren:
228    
229     use AnyEvent;
230     use AnyEvent::Strict;
231    
232     # jetzt wird brutal geprüft.
233    
234 root 1.3 Ich gebe zu, das war sicher noch nicht der Brüller, aber sehen wir
235 root 1.1 weiter:
236    
237     =head2 Anyevent::Util
238    
239     Dies ist meine Grabbelkiste für nützliche aber eklige Funktionen:
240    
241     =over 4
242    
243     =item fork_call BLOCK $callback
244    
245     Führt den angegebenen BLOCK in einem separaten Prozess aus und ruft
246     danach den $callback mit den Resultatwerten auf. Ist ideal, um lange
247     Berechnungen in einen separaten Prozess zu verlagern:
248    
249     fork_call {
250     find_primes_till 1e9
251     } sub {
252     warn "alle primzahen bis 10**9: ", join " ", @_;
253     };
254    
255     Die Funktion leaked allerdings unter Windows, aber ich habe bisher noch
256 root 1.3 keinen Weg gefunden, unter einem native-win32-Perl zu forken und das Kind
257     sauber zu beenden (ich glaube, es gibt keinen...).
258 root 1.1
259     =item my $guard = guard BLOCK
260    
261     Führt den angegebenen BLOCK aus, wenn C<$guard> zerstört wird. Ist
262     bei ereignisgesteuerter Programmierung total hilfreich, um Sachen
263     aufzuräumen.
264    
265     Wenn es vorhanden ist, benutzt AnyEvent das C<Guard>-Modul (ja, das ist
266     Schleichwerbung).
267    
268     =item fh_nonblocking $fh, $nonblocking
269    
270     Einen File Handle non-blocking zu machen, ist nicht ganz einfach (Windows,
271     Windows, kaputt, kaputt...). C<AnyEvent::Util> erledigt dies mit
272     furchtbaren Hacks unter Windows und elegant überall sonst.
273    
274     =back
275    
276     Immer noch nicht überzeugt? Ok, dann machen wir mal mit
277     Netzwerkprogrammierung weiter:
278    
279    
280     =head2 AnyEvent::Socket
281    
282     Sockets in Perl haben ein paar gravierende Nachteile: non-blocking
283     connects sind extrem umständlich, IPv6 und IPv4 brauchen völlig
284     inkompatible APIs, DNS blockiert den gesamtem Prozess und liefert darüber
285     hinaus auch nur altmodische IP-Adressen.
286    
287     Anders mit AnyEvent::Socket:
288    
289     tcp_connect "www.google.com", "80", sub {
290     my ($fh) = @_
291     or die "www.google.com: $!";
292    
293     ...
294     };
295    
296     Dieser Aufruf löst zuerst C<www.google.com> auf - im Hintergrund, ohne
297     das Programm anzuhalten - und baut dann, ebenfalls im Hintergrund, eine
298     TCP-Verbindung dorthin auf.
299    
300     Es versteht sich von selbst, daß Multi-Homed Hosts genauso unterstützt
301     werden wie IPv6, und das ohne zusätzliche XS-Module.
302    
303 root 1.3 C<tcp_connect> kann aber noch mehr. Z.b. auf Jabber-Server connecten, was
304 root 1.1 mit Perl alleine fast unmöglich ist, da man mit Perl keine SRV-Records
305     auflösen kann:
306    
307     tcp_connect "jabber.org", "xmpp-server=5269", sub {
308     # Die pseudo-XML-Kacke parsed ihr bitte selbst...
309     }, 60; # <- timeout
310    
311     Der Name C<tcp_connect> ist leider etwas naiv, tatsächlich werden auch
312 root 1.3 andere Protokolle unterstützt, z.B. local unix Sockets:
313 root 1.1
314     tcp_connect "unix/", "/tmp/.X11-unix/X0", sub { ...
315    
316     Listening-Sockets funktionieren prinzipiell genauso einfach, z.B. hier
317     für einen TCPv6-Port:
318    
319     tcp_server "::", 80, sub {
320     my ($fh, $host, $port) = @_;
321    
322     # jede neue Verbindung führt zu einem Aufruf dieses Callbacks
323     };
324    
325     Oder einen beliebigen TCPv4-Port:
326    
327     tcp_server "0", undef, sub {
328     my ($fh, $host, $port) = @_;
329     ...
330     }, sub {
331     my ($thishost, $thisport) = @_;
332    
333     warn "bound to port $thisport\n";
334     };
335    
336     Leider muss man sich selbst darum kümmern, ob IPv6-Sockets auch auf IPv4
337     hören - üblicherweise ja, aber die BSDs haben natürlich mal wieder
338     verbockt und halten sich nicht ans RFC.
339    
340 root 1.3 Komplizierteres ist immer möglich - anders als z.B. mit C<IO::Socket> hat
341 root 1.1 man volle Kontrolle über die eigentliche Socket und braucht nicht für
342     jeden etwas spezielleren Wunsch extra Support.
343    
344     Und anders als bei anderen Lösungen funktionieren diese Funktionen auch
345     unter Windows korrekt (modulo Tk, daß wie üblich zu kaputt ist, um
346     non-blocking connects stabil zu kriegen, aber AnyEvent arbeitet auch um
347     diese Bugs herum).
348    
349     Neben diesen beiden Funktionen gibt es in AnyEvent::Socket eine Unmenge an
350     Utility-Funktionen zum parsen/anzeigen von IP-Adressen, Socket-Adressen
351     und DNS:
352    
353     $ipn = parse_ipv4 $dotted_quad
354     $ipn = parse_ipv6 $textual_ipv6_address
355     $ipn = parse_address $text
356     $text = AnyEvent::Socket::aton $ipn
357     ($host, $service) = parse_hostport $string[, $default_service]
358     $sa_family = address_family $ipn
359     $text = format_address $ipn
360     $text = AnyEvent::Socket::ntoa $ipn
361     inet_aton $name_or_address, $cb->(@addresses)
362     $sa = AnyEvent::Socket::pack_sockaddr $service, $host
363     ($service, $host) = AnyEvent::Socket::unpack_sockaddr $sa
364     resolve_sockaddr $node, $service, $proto, $family, $type, $cb->([$family, $type, $proto, $sockaddr], ...)
365    
366     Hier verweise ich auf die Dokumentation. Einzig C<parse_hostport>
367     möchte ich genauer erklären: Selbst die Aufgabe, einen Hostnamen und
368     einen Port anzugeben, ist nicht ganz einfach wenn man es richtig machen
369     will. C<parse_hostport> nimmt ein oder zwei Strings und zerlegt diesen in
370     Host und Port, z.B. diese:
371    
372     www.linux.org
373     www.x.de:443
374     www.x.de:https=443
375     127.1:22
376     ::1
377     affe::1
378     [10.0.1]:80
379     [www.x.org] 17
380     10.0.0.1 smtp
381    
382     Richtig, IPv6 macht das ganze deutlich komplexer. Und IPv6 ist die
383     Zukunft, ob man das nun gut findet oder nicht :/
384    
385     Ach ja, Stichwort IPv6 - es kann auch furchtbar nervig sein, wenn
386     Programme grundsätzlich die IPv6-Adresse bevorzugen, die gerade nicht
387     erreichbar ist. Der Standard bei AnyEvent ist zur Zeit IPv4 den
388     Vorzug zu geben, was sich allerdings über die Environment-Variable
389     C<PERL_ANYEVENT_PROTOCOLS> beeinflussen lässt.
390    
391    
392     =head2 AnyEvent::DNS
393    
394     Nur am Rande möchte ich AnyEvent::DNS erwähnen. Ursprünglich war es nur
395     dazu gedacht, die Adressen für C<AnyEvent::Socket> zu resolven. Das Modul
396     ist aber ein kompletter Stub-Resolver, der beliebige DNS-Record-Typen,
397     EDNS0, IPv6 und virtual circuit mode supported.
398    
399     Das Modul ist in der Praxis ca. halb so schnell wie z.b. EV::ADNS (braucht
400     natürlich viel mehr Speicher, blockiert aber im Gegensatz zu EV::ADNS
401     nie).
402    
403     Es gibt Hilfsunktionen (hier nur eine Auswahl):
404    
405     AnyEvent::DNS::a $domain, $cb->(@addrs)
406     AnyEvent::DNS::mx $domain, $cb->(@hostnames)
407     AnyEvent::DNS::srv $service, $proto, $domain, $cb->(@srv_rr)
408     AnyEvent::DNS::ptr $domain, $cb->(@hostnames)
409     AnyEvent::DNS::reverse_lookup $ipv4_or_6, $cb->(@hostnames)
410     AnyEvent::DNS::reverse_verify $ipv4_or_6, $cb->(@hostnames)
411    
412     Und eine Resolver-Klasse:
413    
414     use Data::Dumper;
415     use AnyEvent::DNS;
416     AnyEvent::DNS::resolver->resolve (
417     "google.com", "*", my $cv = AnyEvent->condvar);
418     warn Dumper [$cv->recv];
419    
420     # gekürztes Ergebnis:
421     # [
422     # [ 'google.com', 'soa', 'in', 'ns1.google.com', 'dns-admin.google.com',
423     # 2008052701, 7200, 1800, 1209600, 300 ],
424     # [
425     # 'google.com', 'txt', 'in',
426     # 'v=spf1 include:_netblocks.google.com ~all'
427     # ],
428     # [ 'google.com', 'a', 'in', '64.233.187.99' ],
429     # [ 'google.com', 'mx', 'in', 10, 'smtp2.google.com' ],
430     # [ 'google.com', 'ns', 'in', 'ns2.google.com' ],
431     # ]
432    
433    
434     =head2 AnyEvent::Handle
435    
436     Nun zum ehrgeizigsten Teil der Neuerungen: C<AnyEvent::Handle>.
437    
438     Die Probleme, die dieses Modul lösen möchte, kommen in der Praxis
439     häufig vor: Formatted-I/O, Pipelining und TLS-Verschlüsselung.
440    
441     Früher habe ich immer ad-hoc Lösungen für diese Probleme implementiert,
442     da mir schlicht die Erfahrung gefehlt hat, wie man alle diese Features in
443     ein allgemeines Perl-Modul "gießt".
444    
445     C<AnyEvent::Handle> versucht diese Lösung zu
446     sein: AnyEvent::Handle-Objekte sind Wrapper um existierende File
447     Handles. Im folgenden beschreibe ich die Lösung, die AnyEvent::Handle
448     für die oben beschriebenen Probleme bietet:
449    
450     =over 4
451    
452     =item Formatted I/O
453    
454     Um auf ein AnyEvent::Handle-Objekt zu schreiben, benutzt man
455     C<push_write>. Das C<push> deutet darauf hin, daß es einen Puffer für
456     die Daten gibt, und C<push_write> hängt die Daten einfach an diesen an:
457    
458     $hdl->push_write ("GET / HTTP/1.0\015\012\015\012");
459    
460     Mit mehr als einem Argument fordert man zusätzliche Formatierungen an,
461     die meisten dieser Formatierungen gibt es sowohl für die Schreib- als
462     auch die Leseseite:
463    
464     $hdl->push_write (netstring => "xyz"); # djb netsrings
465     $hdl->push_write (packstring => "w", "data"); # benutzt pack()
466     $hdl->push_write (json => [1, 2, 3, 4]); # benutzt JSON
467     $hdl->push_write (storable => $ref); # benutzt Storable
468    
469     Schreiben ist einfach, Lesen ist schwieriger. Anders als beim Schreiben
470     enthält der Puffer keine Daten, sondern die Callbacks, die der Reihe nach
471     aufgerufen werden, wenn Daten eintreffen.
472    
473     Die Flexibilität entsteht dadurch, daß man Callbacks ans Ende des Puffers anhängen kann:
474    
475     $hdl->push_read (json => sub { my $data = $_[1] });
476    
477     Aber auch vor dem Anfang einschieben kann:
478    
479     $hdl->unshift_read (json => sub { my $data = $_[1] });
480    
481     Interessant ist dies vor allem, weil man hierdurch recht einfach auch
482     komplexe Protokolle mit Pipelining implementieren kann.
483    
484     Man kann jederzeit eigene Typen global für alle Handles hinzufügen, die
485     existierenden Typen sind neben denselben wie für die Schreibrichtung:
486    
487     $hdl->push_read (line => $eol, $cb); # zeilen
488     $hdl->push_Read (regex => $accept[, $reject[, $skip]); # uiuiuiui
489    
490     =item Pipelining
491    
492     Pipelining bedeutet, daß man auf einer bestehenden Verbindung mehrere
493     Anfragen gleichzeitig losschickt. Die Herausforderung liegt darin, daß
494     man beim Empfang der Antworten flexibel auf Ausnahmen reagieren können
495     muss.
496    
497     Bei HTTP beispielsweise weiß man erst nach Parsen des Headers, wie lang
498     der Body wird.
499    
500     AnyEvent::Handle erledigt dies mit einer Kombination aus C<push_read> und
501     C<unshift_read>:
502    
503     # sende requests
504     for (@urls) {
505     $hdl->push_write ("GET $_ HTTP/1.0\015\012\015\012");
506     }
507    
508     # parse antworten
509     for (@urls) {
510     # lese header
511     $hdl->push_read (line => "\015\012\015\012", sub {
512     my ($hdl, $header) = @_;
513    
514     my $content_length = extract "Content-Length", $header;
515    
516     $hdl->unshift_read (chunk => $content_length, sub {
517     my ($hdl, $body) = @_;
518    
519     # fertig
520     });
521     });
522     }
523    
524     Der springende Punkt ist, daß C<unshift_read> erst I<nach> dem Empfang
525     des Headers ausgeführt wird. Dadurch kann man z.B. verschiedene Arten von
526     Antworten parsen, oder auf unerwartete Fehler reagieren, obwohl vielleicht
527     schon Antworten auf die nächsten Requests empfangen wurden.
528    
529     =item TLS/SSL
530    
531     TLS ist der Horror. Nicht nur, aber vor allem auch wegen der grauenvollen
532     OpenSSL-API (GnuTLS ist geringfügig besser, doch sucht man vergebens nach
533     einem guten Perl-Modul dafür). Der Beweis dafür ist, daß es praktisch
534     kein Modul gibt, daß non-blocking TLS connects korrekt und wirklich
535     non-blocking durchführt.
536    
537     Es hilft auch nicht gerade, daß Net::SSLeay nur einen Bruchteil der
538     OpenSSL-API umsetzt.
539    
540     AnyEvent::Handle (to boldly go...) versucht einen ganz neuen Ansatz für
541     diese Problematik, bei der OpenSSL vom eigentlichen File Handle komplett
542     getrennt wird, d.h. gar keinen Zugriff auf diesen hat. Dadurch wird
543     garantiert, daß OpenSSL auf gar keinen Fall blockieren kann.
544    
545 root 1.2 Ganz wie der Rest von AnyEvent ist einfach einfach: wenn man zu einem
546     TLS-Server connecten möchte, setzt man C<tls> auf C<"connect">, als
547     TLS-Server dagegen setzt man es auf C<"accept">.
548    
549     Hat man kompliziertere Ansprüche, wie Zertifikate oder
550     Verification-Callbacks, so kann man sein eigenes Net::SSLeay::CTX-Objekt
551     oder das Net::SSLeay-Objekt für die Verbindung selbst übergeben.
552    
553     Selbstverständlich kann man den TLS-Handshake zu einem beliebigen
554     Zeitpunkt beginnen, nicht nur am Anfang der Verbindung.
555    
556 root 1.1 =back
557    
558 root 1.2 Mit AnyEvent::Handle wird manches erstaunlich einfach. Hier ist z.B. ein
559     (ganz primitiver) HTTPS-Client (übrigens das komplette Programm):
560 root 1.1
561     use AnyEvent;
562     use AnyEvent::Socket;
563     use AnyEvent::Handle;
564    
565     my $cv = AnyEvent->condvar;
566    
567     tcp_connect "www.google.com", "443", sub {
568     my ($fh) = @_ or die;
569    
570     my $hdl; $hdl = new AnyEvent::Handle
571     fh => $fh,
572     timeout => 60,
573     tls => "connect",
574     on_eof => sub {
575     undef $hdl; # gibt handle frei
576     $cv->send; # isch hab' ferdisch
577     },
578     on_read => sub {
579     my ($hdl) = @_;
580     print $hdl->{rbuf};
581     $hdl->{rbuf} = "";
582     };
583    
584     $hdl->push_write ("GET / HTTP/1.0\015\012\015\012");
585     };
586    
587     $cv->recv;
588    
589 root 1.2 Darüber hinaus gibt es eine Menge Parameter, mit dem man Verhalten,
590     Fehlerbehandlung, Ressourcenbenutzung auf seine Anforderungen abstimmen
591     kann. Für ganz spezielle Anwendungen kann man von AnyEvent::Handle auch
592     eigene Klassen ableiten, aber in den meisten Fällen ist dies unnötig.
593    
594     Ein Nachteil von AnyEvent::Handle ist allerdings, daß die Abstraktion
595     selbst nicht kostenlos ist: Methodenaufrufe in Perl sind vergleichsweise
596     langsam, und AnyEvent::Handle benutzt sehr viele davon. In den meisten
597     Fällen merkt man davon allerdings nichts, da der Overhead durch
598     AnyEvent::Handle immer noch sehr gering ist, wenn man mit den Daten auch
599     noch etwas tun möchte.
600    
601 root 1.1 =back
602    
603    
604     =head2 Benchmarks
605    
606 root 1.2 Ich bin es gewohnt, meine eigene Lösungen zu schreiben, notfalls immer
607     und immer wieder. Bevor ich eine (hilfreiche) Abstraktion ruhigen
608     Gewissens benutzen kann, muss ich immer erst wissen, wie viel sie kostet,
609     damit ich eine vernünftige Abwägung machen kann.
610    
611     Deshalb habe ich drei Benchmarks durchgeführt, um herauszufinden, wie
612     hoch der Overhead von AnyEvent gegenüber der direkten Benutzung von
613     Event-Bibliotheken ist, und wie verschiedene Event-Bibliotheken bei
614     typischen Server-Situationen skalieren, sowohl für Server mit sehr vielen
615     Verbindungen, als auch für Server mit sehr wenigen.
616    
617     =head3 Benchmark 1: Overhead
618    
619     Um den Overhead von AnyEvent selbst zu testen, erzeugt dieser Benchmark
620     sehr viele Timer (mit einem Time-out von 0 Sekunden) und ebensoviele
621     I/O watcher auf STDOUT (üblicherweise eine tty), der auf den
622     "schreibbar"-Zustand wartet.
623    
624     Dann lässt er alle Watcher genau einmal ihren Callback aufrufen und
625     zerstört die Watcher dann.
626    
627     Gemessen wird die Zeit, die es jeweils braucht, einen Watcher zu erzeugen,
628     den Callback auszuführen und den Watcher wieder zu zerstören.
629    
630     Die Kernel-Schnittstelle sollte einen relativ geringen Einfluss besitzen,
631     sofern die Event-Bibliothek einigermaßen effizient implementiert wurde,
632     da nur ein einziges mal ein einziger File-Descriptor abgefragt werden
633     muss.
634    
635     (Der Benchmark liegt AnyEvent als F<eg/bench> bei).
636    
637     Die Spalten in der Tabelle haben folgende Bedeutung:
638    
639     I<Watcher> ist die Anzahl der erzeugten Watcher-Objekte, d.h. die Anzahl
640     der Timer + I/O-Watcher.
641    
642     I<Bytes> ist die Anzahl der RAM-Bytes, die ein Watcher-Objekt im Schnitt
643     verbraucht. Dabei wird der Perl- und C-Anteil gezählt.
644    
645     I<Create> ist die durchschnittliche Zeit für die Erzeugung eines Watchers
646     in millionstel Sekunden.
647    
648     I<Invoke> ist die Zeit, in millionstel Sekunden, die die Ausführung des
649     Callbacks dauerte. Der Callback selbst zählt lediglich eine Variable
650     herunter.
651    
652     I<Destroy> schließlich ist die durchschnittliche Zeit für das freigeben
653     eines Watcher-Objektes, in millionstel Sekunden.
654    
655     Alle Benchmarks wurden auf einem Core2-Quad/3.6GHz durchgeführt, wobei
656     das Programm mit Echtzeitpriorität auf CPU #3 lief.
657    
658     Name Watcher Bytes Create Invoke Destroy Hinweise
659 root 1.3 /uSec /uSec
660 root 1.2 EV/EV 400000 224 0.47 0.35 0.27 EV direkt
661     EV/Any 100000 224 2.88 0.34 0.27 EV über AnyEvent
662     Perl/Any 100000 452 4.13 0.73 0.95 AnyEvent/pure perl
663     Event/Event 16000 517 32.20 31.80 0.81 Event direkt
664     Event/Any 16000 590 35.85 31.55 1.06 Event über AnyEvent
665     Glib/Any 16000 1357 102.33 12.31 51.00 >quadratisches Wachstum
666     Tk/Any 2000 1860 27.20 66.31 14.00 SEGV bei >> 2000 watchers
667     POE/Event 2000 6328 109.99 751.67 14.02 via POE::Loop::Event
668     POE/Select 2000 6027 94.54 809.13 579.80 via POE::Loop::Select
669    
670     Wie erwähnt, ist der Benchmark so designed, daß das Kernel-Interface
671     (select, epoll etc.) keinen Einfluss hat. Das bedeutet, daß die
672     Skalierbarkeit der Event-Bibliothek hier I<nicht> gemessen wird.
673    
674     Die Anzahl der Watcher wurde so gewählt, daß die Ausführungszeit für
675     jede Event-Bibliothek ähnlich war: würde man mit EV weniger Watcher
676     wählen, bekäme man keine aussagekräftigen Zahlen, würde man mit Tk
677     mehr wählen, würde es crashen, und würde man bei Glib oder POE mehr
678 root 1.3 wählen, würde ich wohl noch nächstes Jahr auf die Ergebnisse
679 root 1.2 warten.
680    
681     Wie man sieht, ist die Ausführung von Callbacks und das Zerstören von Watchern
682     bei EV direkt (ohne AnyEvent) und bei AnyEvent mit EV als backend identisch, was daran liegt, daß AnyEvent keinerlei Overhead hinzufügt.
683    
684     Lediglich beim Erzeugen von Watchern ist AnyEvent+EV deutlich langsamer
685     als EV direkt. Das liegt daran, daß AnyEvent a) einen Methodenaufruf und
686     b) benannte Parameter benutzt. Diese beiden Umstände machen das Erzeugen
687     von Watchern mehr als fünf mal langsamer als die direkte Benutzung von
688     EV.
689    
690     Auch ist der Speicherverbrauch mit durchschnittlich 224 Bytes bei beiden
691     gleich.
692    
693     Sehr erfreulich ist auch, daß die Pure-Perl Event-Implementation nicht
694     viel hinterherhinkt: Erzeugen von Watchern und die Callback-Aufrufe
695     sind ungefähr halb so schnell wie mit der stark optimierten libev
696     C-Bibliothek. Der Speicherverbrauch ist ebenfalls noch im Rahmen und liegt
697     ca. beim doppelten dessen von EV.
698    
699     Etwas enttäuscht hat mich Event: Event war meine Bibliothek der Wahl, ich
700     hielt sie für sehr schnell und korrekt, musste aber im letzten Jahrzehnt
701     einige größere Design-Schwächen erkennen.
702    
703     Überrascht hat mich allerdings, wie viel langsamer Event gegenüber einer
704     Pure-Perl Implementation ist. Tatsächlich habe ich einige Zeit mit dem
705 root 1.3 Quellcode von Event verbracht und musste feststellen,daß Event in der Tat
706 root 1.2 gewaltigen Aufwand beim Aufruf von Callbacks betreibt, was sich in der
707     Zeit niederschlägt. Die langsame Erzeugungszeit liegt dagegen schlicht
708     daran, daß jeder Parameter intern in einen dynamischen Methodenaufruf
709     umgesetzt wird.
710    
711     Wie man am Speicherverbrauch und dem Zeitunterschied sieht, ist die
712     direkte Benutzung von Event etwas effizienter als den Umweg über AnyEvent
713     zu gehen, allerdings ist der Overhead im Vergleich zur Langsamkeit von
714     Event sehr gering.
715    
716     Wie man an den anderen Zeilen sieht, liegt Event allerdings recht
717 root 1.3 gut: Glib ruft Callbacks zwar schneller auf, die anderen Zeiten sind aber grauenhaft.
718 root 1.2
719     Auch Tk (sofern es nicht crasht :) ist nicht wirklich schneller, und POE
720     ist jenseits von Gut und Böse.
721    
722     Tatsächlich ist die Implementation von AnyEvent auf POE nicht sehr
723     effizient, da POE dies ausschließt. Wie der nächste Benchmark beweist,
724     ist POE allerdings unter realistischen Bedingungen genauso langsam.
725    
726     Eine anderen Sicht der obigen Resultate ist, daß die Behandlung
727 root 1.3 eines Ereignisses mit EV ca. 1_600 Taktzyklen, mit AnyEvents Pure Perl
728     Implementation ca. 3_100 Zyklen und mit POE beinahe 3_000_000 Taktzyklen
729     benötigt_.
730 root 1.2
731     =head3 Benchmark 2: ein großer Server
732    
733     Was den AnyEvent-Overhead angeht, reicht mir der obige Benchmark völlig,
734     um mich zu beruhigen: der Overhead ist, abgesehen von der schnellsten
735     Event-Bibliothek, gering.
736    
737     Um die Pure-Perl Event-Bibliothek von AnyEvent zu testen, muss aber
738     ein anderer Benchmark her. Außerdem wollte ich unbedingt wissen, wie
739     verschiedene Systeme in der Praxis abschneiden.
740    
741     Um einen großen Server zu simulieren, gibt es ein paar
742     Standardbenchmarks. Einer davon ist es, sehr sehr viele Socketpaare zu
743     erzeugen. Auf der einen Seite jedes Paares ist ein "Server", der ein
744     einzelnes Octet liest, und dieses dann auf eine zufällige andere Socket
745 root 1.3 schreibt. Jedes Socketpaar hat einen assoziierten Timer, der bei jeder
746 root 1.2 Aktivität zurückgesetzt wird.
747    
748     Auf diese Weise wandern die Octets auf einem Teil der Verbindungen hin und
749     her, was in etwa einem realen Server entspricht: sehr viele Verbindungen,
750     aber nur ein kleiner Teil davon ist in jeder Iteration aktiv.
751    
752 root 1.3 Im folgenden werden 10_000 Socketpaare (d.h. 20_000 Sockets) erzeugt, und
753 root 1.2 davon sind jeweils 100 "aktiv".
754    
755     (Der Benchmark liegt AnyEvent als F<eg/bench2> bei).
756    
757     Die Spalten bedeuten im einzelnen:
758    
759     I<Create> ist die Zeit, die es braucht, um ein Socketpaar zu erzeugen und
760     alle Watcher zu registrieren, wieder in millionstel Sekunden.
761    
762     I<Request> ist bei weitem die wichtigste Größe. Sie gibt an, wie lange
763     es im Schnitt dauert, um eine "Anfrage" zu bearbeiten und den Timeout
764     zurückzusetzen.
765    
766     Name Create Request
767 root 1.3 /uSec /uSec
768 root 1.2 EV 69.01 11.16
769     Perl 73.32 35.87
770     Event 212.62 257.32
771     Glib 651.16 1896.30
772     POE 349.67 12317.24 mit POE::Loop::Event
773    
774     Dieser Benchmark misst nun direkt die Skalierbarkeit und die
775     Geschwindigkeit der Event-Bibliothek.
776    
777     EV hat hier einen großen Vorteil, da es epoll, einen weitaus
778     effizienteren Mechanismus als select oder poll, benutzen kann, während
779     alle anderen entweder select oder poll benutzen.
780    
781     Wenig verwunderlich ist EV hier wieder mit Abstand am schnellsten.
782    
783 root 1.3 Sehr erstaunt war ich über das sehr gute Abschneiden der Pure-Perl
784 root 1.2 Implementation. Sie ließ die anderen C-Bibliotheken weit hinter
785     sich. Möglicherweise liegt der Grund hierfür darin, daß AnyEvent
786     ganz ähnliche Algorithmen wie EV benutzt um I/O-Watcher und Timer zu
787     verwalten, und ansonsten sehr abgespeckt ist.
788    
789     Event leidet sicher daran, daß es so teuer ist, Watcher zu erzeugen und
790     upzudaten.
791    
792     Woran Glib leidet, ist schlichtweg unglaubliche Ineffizienz: Alle
793     Watcher werden bei jeder Iteration vielmals angeschaut, teilweise
794     sogar verglichen. Ich glaube nicht, daß man eine derart ineffiziente
795     Event-Bibliothek erhielte, wenn man sich hinsetzte und einfach drauf los
796 root 1.3 schriebe ohne sich Gedanken zu machen. Tatsächlich ist Glib auch nicht
797 root 1.2 dafür gedacht, effizient zu sein oder mehr als einen File Descriptor zu
798     unterstützen (den zum X-Server nämlich).
799    
800     POE ist sicherlich etwas langsamer, als es sein könnte, da für jede
801     Verbindung drei "sessions" eingesetzt wurden, während POE eine Session
802     pro "Verbindung" vorschlägt. Allerdings ist derlei Kritik am Benchmark
803     irrelevant: Auch in einem echten Server würde man für jede Session eine
804     Session benutzen, und selbst wenn POE dreimal schneller würde wäre es
805     immer noch über 100 mal langsamer als die Pure-Perl Event-Implementation
806     von AnyEvent.
807    
808 root 1.3 Im übrigen wurde in diesem Benchmark sogar die Pure-Perl Version von POE durch
809 root 1.2 eine optimierte Variante ersetzt wurde, die das C<Event>-Modul benutzt.
810    
811 root 1.3 =head3 Benchmark 3: ein klitzekleiner Server
812 root 1.2
813     Benchmarks für riesige Systeme sind sicher wichtig, aber wenn man "nur
814 root 1.3 eben" mal AnyEvent benutzt, sollte es auch schnell sein, wenn man nur
815 root 1.2 sehr wenige aktive Verbindungen hat.
816    
817     Im folgenden wurde daher nur acht Socketpaare benutzt, von denen jeweils drei aktiv sind:
818    
819     Name Create Request
820 root 1.3 /uSec /uSec
821 root 1.2 EV 20.00 6.54
822     Perl 25.75 12.62
823     Event 81.27 35.86
824     Glib 32.63 15.48
825     POE 261.87 276.28 mit POE::Loop::Event
826    
827 root 1.3 Wie man sieht, ändert sich nichts drastisch: Glib ist nun so schnell
828 root 1.2 wie die anderen, aber EV und AnyEvents Pure-Perl Implementation sind
829     trotzdem schneller.
830    
831     Während POE weiterhin stark hinterherhinkt, für drei Verbindungen aber
832     absolut adäquat ist :->
833    
834    
835 root 1.1 =head2 Ausblick auf CPAN
836 root 1.2
837     AnyEvent existiert nicht in Isolation: Es gibt inzwischen eine stattliche
838     Anzahl von CPAN-Modulen die AnyEvent und nur AnyEvent als Abhängigkeit
839 root 1.3 besitzen. Für AnyEvent ist es nicht so wichtig wie für andere
840 root 1.2 "Frameworks" (wie POE), viele weitere CPAN-Module zu benutzen, da
841     AnyEvent-Module ja mit anderen Frameworks kombiniert werden können,
842     umgekehrt ist dies allerdings nicht der Fall (AnyEvent + POE Programm
843     geht, POE + Tk-Programm geht nicht).
844    
845     Hier ist eine fast erschöpfende Auswahl von AnyEvent-Modulen auf CPAN:
846    
847     =over 4
848    
849     =item AnyEvent::HTTP
850    
851 root 1.3 Ein ganz einfacher HTTP-Client. Da man mit LWP keine parallelen Abfragen
852 root 1.2 durchführen im selben Prozess kann, ist es recht hilfreich :)
853    
854 root 1.3 =item AnyEvent::AIO
855 root 1.2
856     Integriert IO::AIO transparent in AnyEvent. AnyEvent::AIO ist ein ideales
857 root 1.3 Pendant zu AnyEvent: AnyEvent abstrahiert non-blocking I/O, IO::AIO
858 root 1.2 abstrahiert asynchrones I/O.
859    
860     =item AnyEvent::DBI
861    
862     Langsames, aber asynchrones, DBI-Frontend.
863    
864     =item AnyEvent::CouchDB
865    
866     Eine Schnittstelle zur CouchDB. Ein must have!
867    
868     =item AnyEvent::BDB
869    
870     Asynchrone Schnittstelle zur guten alten BerkelyDB.
871    
872     =item AnyEvent::IRC
873    
874     Event basiertes IRC.
875    
876     =item AnyEvent::XMPP
877    
878     Alternative zum eigenen Parser für Jabber-Pseudo-XML.
879    
880     =item AnyEvent::FastPing
881    
882     Wenn man mal eine Million Ping-Pakete pro Sekunde verschicken will. Eignet
883     sich ideal um Firewalls abzuschießen :)
884    
885     =item AnyEvent::Mojo
886    
887     Wenn ich's bloß wüsste...
888    
889     =item AnyEvent::HTTPD
890    
891     Ein einfacher Webserver zum Einbetten in die eigene Applikation.
892    
893     =item Coro::AnyEvent
894    
895     Die Kombination von Coro-Threads und AnyEvent ist ideal - komplexe Logik
896     kann man bequem per Thread implementieren, Low-Level Event-Handling geht
897     meist per AnyEvent angenehmer.
898    
899     =back