ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Intro.pod
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Intro.pod (file contents):
Revision 1.4 by root, Sat May 31 01:29:30 2008 UTC vs.
Revision 1.5 by root, Sat May 31 01:41:22 2008 UTC

392 392
393=head1 Network programming and AnyEvent 393=head1 Network programming and AnyEvent
394 394
395So far you have seen how to register event watchers and handle events. 395So far you have seen how to register event watchers and handle events.
396 396
397This is a great basis to write network clients and servers, and might be 397This is a great foundation to write network clients and servers, and might be
398all that your module (or program) ever requires, but writing your own I/O 398all that your module (or program) ever requires, but writing your own I/O
399buffering again and again becomes tedious, not to mention that it attracts 399buffering again and again becomes tedious, not to mention that it attracts
400errors. 400errors.
401 401
402While the core L<AnyEvent> module is still small and self-contained, 402While the core L<AnyEvent> module is still small and self-contained,
527 $cv 527 $cv
528 } 528 }
529 529
530This isn't too complicated, just a function with two parameters, which 530This isn't too complicated, just a function with two parameters, which
531creates a condition variable, returns it, and while it does that, 531creates a condition variable, returns it, and while it does that,
532initiates a TCP connect to the passed C<$host>. The condition variable 532initiates a TCP connect to C<$host>. The condition variable
533will be used by the caller to receive the finger response. 533will be used by the caller to receive the finger response.
534 534
535Since we are event-based programmers, we do not wait for the connect to 535Since we are event-based programmers, we do not wait for the connect to
536finish - it could block your program for a minute or longer! 536finish - it could block your program for a minute or longer! Instead,
537 537we pass the callback it should invoke when the connect is done to
538Instead, we pass C<tcp_connect> the callback it should invoke when the 538C<tcp_connect>. If it is successful, our callback gets called with the
539connect is done. If it is successful, our callback gets passed the socket
540handle as first argument, otherwise, nothing will be passed. 539socket handle as first argument, otherwise, nothing will be passed to our
540callback.
541 541
542Let's look at our callback in more detail: 542Let's look at our callback in more detail:
543 543
544 # the callback gets the socket handle - or nothing 544 # the callback gets the socket handle - or nothing
545 my ($fh) = @_ 545 my ($fh) = @_
546 or return $cv->send; 546 or return $cv->send;
547 547
548The first thing the callback does is indeed save the passed socket handle 548The first thing the callback does is indeed save the socket handle in
549in C<$fh>. When there was an error (no arguments), then our instinct would 549C<$fh>. When there was an error (no arguments), then our instinct as
550tell us to die: 550expert Perl programmers would tell us to die:
551 551
552 my ($fh) = @_ 552 my ($fh) = @_
553 or die "$host: $!"; 553 or die "$host: $!";
554 554
555While this would give good feedback to the user, our program would 555While this would give good feedback to the user, our program would
584 poll => "r", 584 poll => "r",
585 585
586There is a trick here, however: the read watcher isn't stored in a global 586There is a trick here, however: the read watcher isn't stored in a global
587variable, but in a local one - if the callback returns, it would normally 587variable, but in a local one - if the callback returns, it would normally
588destroy the variable and its contents, which would in turn unregister our 588destroy the variable and its contents, which would in turn unregister our
589watcher again. 589watcher.
590 590
591To avoid that, we C<undef>ine the variable in the watcher callback. This 591To avoid that, we C<undef>ine the variable in the watcher callback. This
592means that, when the C<tcp_connect> callback returns, that Perl thinks 592means that, when the C<tcp_connect> callback returns, that perl thinks
593(quite correctly) that the read watcher is still in use - namely in the 593(quite correctly) that the read watcher is still in use - namely in the
594callback. 594callback.
595 595
596The callback itself calls C<sysread> for as many times as necessary, until 596The callback itself calls C<sysread> for as many times as necessary, until
597C<sysread> returns an error or end-of-file: 597C<sysread> returns an error or end-of-file:
614gets destroyed as well. The result is that all resources will be nicely 614gets destroyed as well. The result is that all resources will be nicely
615cleaned up by perl for us. 615cleaned up by perl for us.
616 616
617=head3 Using the finger client 617=head3 Using the finger client
618 618
619Now, we could probably write the same finger client simpler if we used 619Now, we could probably write the same finger client in a simpler way if
620C<IO::Socket::INET>, ignored the problem of multiple hosts and ignored 620we used C<IO::Socket::INET>, ignored the problem of multiple hosts and
621IPv6 and a few other things. 621ignored IPv6 and a few other things that C<tcp_connect> handles for us.
622 622
623But the main advantage is that we can not only run this finger function in 623But the main advantage is that we can not only run this finger function in
624the background, we even can run multiple sessions in parallel, like this: 624the background, we even can run multiple sessions in parallel, like this:
625 625
626 my $f1 = finger "trouble", "noc.dfn.de"; # check for trouble tickets 626 my $f1 = finger "trouble", "noc.dfn.de"; # check for trouble tickets
630 print "trouble tickets:\n", $f1->recv, "\n"; 630 print "trouble tickets:\n", $f1->recv, "\n";
631 print "trouble ticket #1736:\n", $f2->recv, "\n"; 631 print "trouble ticket #1736:\n", $f2->recv, "\n";
632 print "john carmacks finger file: ", $f3->recv, "\n"; 632 print "john carmacks finger file: ", $f3->recv, "\n";
633 633
634It doesn't look like it, but in fact all three requests run in 634It doesn't look like it, but in fact all three requests run in
635parallel. The code waits for the first finger request to finish first, but 635parallel. The code waits for the first finger request to finish first,
636that doesn't keep it from executing all three in parallel. 636but that doesn't keep it from executing all three in parallel, a bug time
637saver.
638
639By the way, you do not actually have to wait in the C<recv> method on an
640AnyEvent condition variable, you can also register a callback:
641
642 $cv->cb (sub {
643 my $response = shift->recv;
644 # ...
645 });
646
647The callback will only be invoked when C<send> was called. In fact,
648instead of returning a condition variable you could also pass a third
649parameter to your finger function, the callback to invoke with the
650response:
651
652 sub finger($$$) {
653 my ($user, $host, $cb) = @_;
654
655What you use is a matter of taste - if you expect your function to be
656used mainly in an event-based program you would normally prefer to pass a
657callback directly.
637 658
638=head3 Criticism and fix 659=head3 Criticism and fix
639 660
640To make this example more real-world-ready, we would not only implement 661To make this example more real-world-ready, we would not only implement
641some write buffering (for the paranoid), but we would also have to handle 662some write buffering (for the paranoid), but we would also have to handle

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines