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

Comparing AnyEvent-MP/MP/Intro.pod (file contents):
Revision 1.33 by root, Mon Aug 31 15:12:49 2009 UTC vs.
Revision 1.34 by root, Mon Aug 31 17:49:02 2009 UTC

528This basically means "monitor $port and kill me when it crashes". And a 528This basically means "monitor $port and kill me when it crashes". And a
529"normal" kill does not count as a crash. This way you can easily link 529"normal" kill does not count as a crash. This way you can easily link
530ports together and make them crash together on errors (but allow you to 530ports together and make them crash together on errors (but allow you to
531remove a port silently). 531remove a port silently).
532 532
533=head3 Port Context
534
535When code runs in an environment where C<$SELF> contains its own port ID
536and exceptions will be caught, it is said to run in a port context.
537
538Since AnyEvent::MP is event-based, it is not uncommon to register
539callbacks from C<rcv> handlers. As example, assume that the port receive
540handler wants to C<die> a second later, using C<after>:
541
542 my $port = port {
543 after 1, sub { die "oops" };
544 };
545
546Then you will find it does not work - when the after callback is executed,
547it does not run in port context anymore, so exceptions will not be caught.
548
549For these cases, AnyEvent::MP exports a special "close constructor" called
550C<psub>, which works just like perl's builtin C<sub>:
551
552 my $port = port {
553 after 1, psub { die "oops" };
554 };
555
556C<psub> stores C<$SELF> and returns a code reference. When the code
557reference is invoked, it will run the code block within the context of
558that port, so exception handling once more works as expected.
559
533=head3 Network Errors and the AEMP Guarantee 560=head3 Network Errors and the AEMP Guarantee
534 561
535I mentioned another important source of monitoring failures: network 562I mentioned another important source of monitoring failures: network
536problems. When a node loses connection to another node, it will invoke all 563problems. When a node loses connection to another node, it will invoke all
537monitoring actions as if the port was killed, even if it is possible that 564monitoring actions as if the port was killed, even if it is possible that
695 mon $server, $client; 722 mon $server, $client;
696 } 723 }
697 724
698 server_connect; 725 server_connect;
699 726
700 my $w = AnyEvent->io (fh => *STDIN, poll => 'r', cb => sub { 727 my $w = AnyEvent->io (fh => 0, poll => 'r', cb => sub {
701 chomp (my $line = <STDIN>); 728 chomp (my $line = <STDIN>);
702 print "> "; 729 print "> ";
703 snd $server, privmsg => $nick, $line 730 snd $server, privmsg => $nick, $line
704 if $server; 731 if $server;
705 }); 732 });
785message, it should probably monitor itself, and the client should not try 812message, it should probably monitor itself, and the client should not try
786to send any messages unless a server is actually connected. 813to send any messages unless a server is actually connected.
787 814
788=head1 PART 3: TIMTOWTDI: Virtual Connections 815=head1 PART 3: TIMTOWTDI: Virtual Connections
789 816
817The chat system developed in the previous sections is very "traditional"
818in a way: you start some server(s) and some clients statically and they
819start talking to each other.
820
821Sometimes applications work more like "services": They can run on almost
822any node and talks to itself on other nodes. The L<AnyEvent::MP::Global>
823service for example monitors nodes joining the network and starts itself
824automatically on other nodes (if it isn't running already).
825
826A good way to design such applications is to put them into a module and
827create "virtual connections" to other nodes - we call this the "bridge
828head" method, because you start by creating a remote port (the bridge
829head) and from that you start to bootstrap your application.
830
831Since that sounds rather theoretical, let's redesign the chat server and
832client using this design method.
833
834Here is the server:
835
836 use common::sense;
837 use AnyEvent::MP;
838 use AnyEvent::MP::Global;
839
840 configure;
841
842 AnyEvent::MP::Global::register $NODE, "eg_chat_server2";
843
844 my %clients;
845
846 sub msg {
847 print "relaying: $_[0]\n";
848 snd $_, $_[0]
849 for values %clients;
850 }
851
852 sub client_connect {
853 my ($client, $nick) = @_;
854
855 mon $client;
856 mon $client, sub {
857 delete $clients{$client};
858 msg "$nick (quits, @_)";
859 };
860
861 $clients{$client} = $client;
862
863 msg "$nick (joins)";
864
865 rcv $SELF, sub { msg "$nick: $_[0]" };
866 }
867
868 warn "server ready.\n";
869
870 AnyEvent->condvar->recv;
871
872It starts not much different, except that this time, we register the node
873port and not any special port - the clients only want to know which node
874the server should be running, and in fact, they could also sue some kind
875of election mechanism or similar.
876
877The interesting change is that no port is created - the server is all
878code, and does nothing. All it does is define a function C<client_connect>
879that expects a client port and a nick as arguments. It then monitors the
880client port and binds a receive callback on C<$SELF> that expects messages
881to broadcast to all clients.
882
883The two C<mon> calls are a bit tricky - the first C<mon> is a shorthand
884for C<mon $client, $SELF>. The second does the normal "client has gone
885away" clean-up action. Both could actually be rolled into one C<mon>
886action.
887
888C<$SELF> is a good hint that something interetsing is going on. And
889indeed, when looking at the client, there is a new function, C<spawn>:
890
891 use common::sense;
892 use AnyEvent::MP;
893 use AnyEvent::MP::Global;
894
895 my $nick = shift;
896
897 configure;
898
899 $| = 1;
900
901 my $port = port;
902
903 my ($client, $server);
904
905 sub server_connect {
906 my $servernodes = AnyEvent::MP::Global::find "eg_chat_server2"
907 or return after 1, \&server_connect;
908
909 print "\rconnecting...\n";
910
911 $client = port { print "\r \r@_\n> " };
912 mon $client, sub {
913 print "\rdisconnected @_\n";
914 &server_connect;
915 };
916
917 $server = spawn $servernodes->[0], "::client_connect", $client, $nick;
918 mon $server, $client;
919 }
920
921 server_connect;
922
923 my $w = AnyEvent->io (fh => 0, poll => 'r', cb => sub {
924 chomp (my $line = <STDIN>);
925 print "> ";
926 snd $server, $line
927 if $server;
928 });
929
930 print "> ";
931 AnyEvent->condvar->recv;
932
933The client is quite similar to the previous one, but instead of contacting
934the server port (which no longer exists), it C<spawn>s a new port on the
935server I<node>:
936
937 $server = spawn $servernodes->[0], "::client_connect", $client, $nick;
938 mon $server, $client;
939
940And of course immediately monitors it. The C<spawn> function creates a new
941port on a remote node and returns its port ID. After creating the port it
942calls a function on the remote node, passing any remaining arguments to
943it, and - most importantly - within the context of the new port. The init
944function can reside in a module (actually it normally I<should> reside
945in a module) - AnyEvent::MP will automatically load the module if the
946function isn't defined.
947
948The C<spawn> function returns immediately, which means you can immediately
949send messages to the port, long before the remote node has even heard
950of our request to create a port on it. In fact, the remote node might
951not even be running. Despite these troubling facts, everything should
952work just fine: if the node isn't running (or the init function throws an
953exception), then the monitor will trigger because the port doesn't exist.
954
955If the spawn message gets delivered, but the monitoring message is not
956because of network problems (monitoring, after all, is implemented by
957passing a message, and messages can get lost), then this connection loss
958will eventually trigger the monitoring action. On the remote node (which
959reciprocally monitors the client) the port will also be cleaned up on
960connection loss. When the node comes up and our monitoring message can be
961delivered it will instantly fail because the port has been cleaned up in
962the meantime.
963
964If your head is spinning by now, that's fine - just keep in mind, after
965creating a port, monitor "the other side" from it, and all will be cleaned
966up just fine.
967
968=head1 PART 4: Services
969
790#TODO 970#TODO
791 971
792=head1 SEE ALSO 972=head1 SEE ALSO
793 973
974L<AnyEvent::MP>
975
976L<AnyEvent::MP::Global>
977
794L<AnyEvent> 978L<AnyEvent>
795
796L<AnyEvent::Handle>
797
798L<AnyEvent::MP>
799
800L<AnyEvent::MP::Global>
801 979
802=head1 AUTHOR 980=head1 AUTHOR
803 981
804 Robin Redeker <elmex@ta-sa.org> 982 Robin Redeker <elmex@ta-sa.org>
805 Marc Lehmann <schmorp@schmorp.de> 983 Marc Lehmann <schmorp@schmorp.de>

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines