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

Comparing AnyEvent-MP/MP.pm (file contents):
Revision 1.36 by root, Thu Aug 6 10:46:48 2009 UTC vs.
Revision 1.49 by root, Thu Aug 13 15:29:58 2009 UTC

8 8
9 $NODE # contains this node's noderef 9 $NODE # contains this node's noderef
10 NODE # returns this node's noderef 10 NODE # returns this node's noderef
11 NODE $port # returns the noderef of the port 11 NODE $port # returns the noderef of the port
12 12
13 $SELF # receiving/own port id in rcv callbacks
14
15 # initialise the node so it can send/receive messages
16 initialise_node; # -OR-
17 initialise_node "localhost:4040"; # -OR-
18 initialise_node "slave/", "localhost:4040"
19
20 # ports are message endpoints
21
22 # sending messages
13 snd $port, type => data...; 23 snd $port, type => data...;
24 snd $port, @msg;
25 snd @msg_with_first_element_being_a_port;
14 26
15 $SELF # receiving/own port id in rcv callbacks 27 # creating/using miniports
28 my $miniport = port { my @msg = @_; 0 };
16 29
30 # creating/using full ports
31 my $port = port;
17 rcv $port, smartmatch => $cb->($port, @msg); 32 rcv $port, smartmatch => $cb->(@msg);
18
19 # examples:
20 rcv $port2, ping => sub { snd $_[0], "pong"; 0 }; 33 rcv $port, ping => sub { snd $_[0], "pong"; 0 };
21 rcv $port1, pong => sub { warn "pong received\n" }; 34 rcv $port, pong => sub { warn "pong received\n"; 0 };
22 snd $port2, ping => $port1;
23 35
24 # more, smarter, matches (_any_ is exported by this module) 36 # more, smarter, matches (_any_ is exported by this module)
25 rcv $port, [child_died => $pid] => sub { ... 37 rcv $port, [child_died => $pid] => sub { ...
26 rcv $port, [_any_, _any_, 3] => sub { .. $_[2] is 3 38 rcv $port, [_any_, _any_, 3] => sub { .. $_[2] is 3
27 39
28 # linking two ports, so they both crash together 40 # create a port on another node
29 lnk $port1, $port2; 41 my $port = spawn $node, $initfunc, @initdata;
30 42
31 # monitoring 43 # monitoring
32 mon $port, $cb->(@msg) # callback is invoked on death 44 mon $port, $cb->(@msg) # callback is invoked on death
33 mon $port, $otherport # kill otherport on abnormal death 45 mon $port, $otherport # kill otherport on abnormal death
34 mon $port, $otherport, @msg # send message on death 46 mon $port, $otherport, @msg # send message on death
35 47
48=head1 CURRENT STATUS
49
50 AnyEvent::MP - stable API, should work
51 AnyEvent::MP::Intro - outdated
52 AnyEvent::MP::Kernel - WIP
53 AnyEvent::MP::Transport - mostly stable
54
55 stay tuned.
56
36=head1 DESCRIPTION 57=head1 DESCRIPTION
37 58
38This module (-family) implements a simple message passing framework. 59This module (-family) implements a simple message passing framework.
39 60
40Despite its simplicity, you can securely message other processes running 61Despite its simplicity, you can securely message other processes running
43For an introduction to this module family, see the L<AnyEvent::MP::Intro> 64For an introduction to this module family, see the L<AnyEvent::MP::Intro>
44manual page. 65manual page.
45 66
46At the moment, this module family is severly broken and underdocumented, 67At the moment, this module family is severly broken and underdocumented,
47so do not use. This was uploaded mainly to reserve the CPAN namespace - 68so do not use. This was uploaded mainly to reserve the CPAN namespace -
48stay tuned! The basic API should be finished, however. 69stay tuned!
49 70
50=head1 CONCEPTS 71=head1 CONCEPTS
51 72
52=over 4 73=over 4
53 74
98 119
99=cut 120=cut
100 121
101package AnyEvent::MP; 122package AnyEvent::MP;
102 123
103use AnyEvent::MP::Base; 124use AnyEvent::MP::Kernel;
104 125
105use common::sense; 126use common::sense;
106 127
107use Carp (); 128use Carp ();
108 129
109use AE (); 130use AE ();
110 131
111use base "Exporter"; 132use base "Exporter";
112 133
113our $VERSION = '0.1'; 134our $VERSION = $AnyEvent::MP::Kernel::VERSION;
135
114our @EXPORT = qw( 136our @EXPORT = qw(
115 NODE $NODE *SELF node_of _any_ 137 NODE $NODE *SELF node_of _any_
116 resolve_node initialise_node 138 resolve_node initialise_node
117 snd rcv mon kil reg psub 139 snd rcv mon kil reg psub spawn
118 port 140 port
119); 141);
120 142
121our $SELF; 143our $SELF;
122 144
146it should know the noderefs of some other nodes in the network. 168it should know the noderefs of some other nodes in the network.
147 169
148This function initialises a node - it must be called exactly once (or 170This function initialises a node - it must be called exactly once (or
149never) before calling other AnyEvent::MP functions. 171never) before calling other AnyEvent::MP functions.
150 172
151All arguments are noderefs, which can be either resolved or unresolved. 173All arguments (optionally except for the first) are noderefs, which can be
174either resolved or unresolved.
175
176The first argument will be looked up in the configuration database first
177(if it is C<undef> then the current nodename will be used instead) to find
178the relevant configuration profile (see L<aemp>). If none is found then
179the default configuration is used. The configuration supplies additional
180seed/master nodes and can override the actual noderef.
152 181
153There are two types of networked nodes, public nodes and slave nodes: 182There are two types of networked nodes, public nodes and slave nodes:
154 183
155=over 4 184=over 4
156 185
157=item public nodes 186=item public nodes
158 187
159For public nodes, C<$noderef> must either be a (possibly unresolved) 188For public nodes, C<$noderef> (supplied either directly to
160noderef, in which case it will be resolved, or C<undef> (or missing), in 189C<initialise_node> or indirectly via a profile or the nodename) must be a
161which case the noderef will be guessed. 190noderef (possibly unresolved, in which case it will be resolved).
162 191
163Afterwards, the node will bind itself on all endpoints and try to connect 192After resolving, the node will bind itself on all endpoints and try to
164to all additional C<$seednodes> that are specified. Seednodes are optional 193connect to all additional C<$seednodes> that are specified. Seednodes are
165and can be used to quickly bootstrap the node into an existing network. 194optional and can be used to quickly bootstrap the node into an existing
195network.
166 196
167=item slave nodes 197=item slave nodes
168 198
169When the C<$noderef> is the special string C<slave/>, then the node will 199When the C<$noderef> (either as given or overriden by the config file)
200is the special string C<slave/>, then the node will become a slave
170become a slave node. Slave nodes cannot be contacted from outside and will 201node. Slave nodes cannot be contacted from outside and will route most of
171route most of their traffic to the master node that they attach to. 202their traffic to the master node that they attach to.
172 203
173At least one additional noderef is required: The node will try to connect 204At least one additional noderef is required (either by specifying it
174to all of them and will become a slave attached to the first node it can 205directly or because it is part of the configuration profile): The node
175successfully connect to. 206will try to connect to all of them and will become a slave attached to the
207first node it can successfully connect to.
176 208
177=back 209=back
178 210
179This function will block until all nodes have been resolved and, for slave 211This function will block until all nodes have been resolved and, for slave
180nodes, until it has successfully established a connection to a master 212nodes, until it has successfully established a connection to a master
181server. 213server.
182 214
183Example: become a public node listening on the default node. 215Example: become a public node listening on the guessed noderef, or the one
216specified via C<aemp> for the current node. This should be the most common
217form of invocation for "daemon"-type nodes.
184 218
185 initialise_node; 219 initialise_node;
220
221Example: become a slave node to any of the the seednodes specified via
222C<aemp>. This form is often used for commandline clients.
223
224 initialise_node "slave/";
225
226Example: become a slave node to any of the specified master servers. This
227form is also often used for commandline clients.
228
229 initialise_node "slave/", "master1", "192.168.13.17", "mp.example.net";
186 230
187Example: become a public node, and try to contact some well-known master 231Example: become a public node, and try to contact some well-known master
188servers to become part of the network. 232servers to become part of the network.
189 233
190 initialise_node undef, "master1", "master2"; 234 initialise_node undef, "master1", "master2";
193 237
194 initialise_node 4041; 238 initialise_node 4041;
195 239
196Example: become a public node, only visible on localhost port 4044. 240Example: become a public node, only visible on localhost port 4044.
197 241
198 initialise_node "locahost:4044"; 242 initialise_node "localhost:4044";
199
200Example: become a slave node to any of the specified master servers.
201
202 initialise_node "slave/", "master1", "192.168.13.17", "mp.example.net";
203 243
204=item $cv = resolve_node $noderef 244=item $cv = resolve_node $noderef
205 245
206Takes an unresolved node reference that may contain hostnames and 246Takes an unresolved node reference that may contain hostnames and
207abbreviated IDs, resolves all of them and returns a resolved node 247abbreviated IDs, resolves all of them and returns a resolved node
343registered. 383registered.
344 384
345The global C<$SELF> (exported by this module) contains C<$port> while 385The global C<$SELF> (exported by this module) contains C<$port> while
346executing the callback. 386executing the callback.
347 387
348Runtime errors wdurign callback execution will result in the port being 388Runtime errors during callback execution will result in the port being
349C<kil>ed. 389C<kil>ed.
350 390
351If the match is an array reference, then it will be matched against the 391If the match is an array reference, then it will be matched against the
352first elements of the message, otherwise only the first element is being 392first elements of the message, otherwise only the first element is being
353matched. 393matched.
494 534
495=item $guard = mon $port 535=item $guard = mon $port
496 536
497=item $guard = mon $port, $rcvport, @msg 537=item $guard = mon $port, $rcvport, @msg
498 538
499Monitor the given port and do something when the port is killed, and 539Monitor the given port and do something when the port is killed or
500optionally return a guard that can be used to stop monitoring again. 540messages to it were lost, and optionally return a guard that can be used
541to stop monitoring again.
542
543C<mon> effectively guarantees that, in the absence of hardware failures,
544that after starting the monitor, either all messages sent to the port
545will arrive, or the monitoring action will be invoked after possible
546message loss has been detected. No messages will be lost "in between"
547(after the first lost message no further messages will be received by the
548port). After the monitoring action was invoked, further messages might get
549delivered again.
501 550
502In the first form (callback), the callback is simply called with any 551In the first form (callback), the callback is simply called with any
503number of C<@reason> elements (no @reason means that the port was deleted 552number of C<@reason> elements (no @reason means that the port was deleted
504"normally"). Note also that I<< the callback B<must> never die >>, so use 553"normally"). Note also that I<< the callback B<must> never die >>, so use
505C<eval> if unsure. 554C<eval> if unsure.
506 555
507In the second form (another port given), the other port (C<$rcvport) 556In the second form (another port given), the other port (C<$rcvport>)
508will be C<kil>'ed with C<@reason>, iff a @reason was specified, i.e. on 557will be C<kil>'ed with C<@reason>, iff a @reason was specified, i.e. on
509"normal" kils nothing happens, while under all other conditions, the other 558"normal" kils nothing happens, while under all other conditions, the other
510port is killed with the same reason. 559port is killed with the same reason.
511 560
512The third form (kill self) is the same as the second form, except that 561The third form (kill self) is the same as the second form, except that
513C<$rvport> defaults to C<$SELF>. 562C<$rvport> defaults to C<$SELF>.
514 563
515In the last form (message), a message of the form C<@msg, @reason> will be 564In the last form (message), a message of the form C<@msg, @reason> will be
516C<snd>. 565C<snd>.
517 566
567As a rule of thumb, monitoring requests should always monitor a port from
568a local port (or callback). The reason is that kill messages might get
569lost, just like any other message. Another less obvious reason is that
570even monitoring requests can get lost (for exmaple, when the connection
571to the other node goes down permanently). When monitoring a port locally
572these problems do not exist.
573
518Example: call a given callback when C<$port> is killed. 574Example: call a given callback when C<$port> is killed.
519 575
520 mon $port, sub { warn "port died because of <@_>\n" }; 576 mon $port, sub { warn "port died because of <@_>\n" };
521 577
522Example: kill ourselves when C<$port> is killed abnormally. 578Example: kill ourselves when C<$port> is killed abnormally.
532sub mon { 588sub mon {
533 my ($noderef, $port) = split /#/, shift, 2; 589 my ($noderef, $port) = split /#/, shift, 2;
534 590
535 my $node = $NODE{$noderef} || add_node $noderef; 591 my $node = $NODE{$noderef} || add_node $noderef;
536 592
537 my $cb = @_ ? $_[0] : $SELF || Carp::croak 'mon: called with one argument only, but $SELF not set,'; 593 my $cb = @_ ? shift : $SELF || Carp::croak 'mon: called with one argument only, but $SELF not set,';
538 594
539 unless (ref $cb) { 595 unless (ref $cb) {
540 if (@_) { 596 if (@_) {
541 # send a kill info message 597 # send a kill info message
542 my (@msg) = @_; 598 my (@msg) = ($cb, @_);
543 $cb = sub { snd @msg, @_ }; 599 $cb = sub { snd @msg, @_ };
544 } else { 600 } else {
545 # simply kill other port 601 # simply kill other port
546 my $port = $cb; 602 my $port = $cb;
547 $cb = sub { kil $port, @_ if @_ }; 603 $cb = sub { kil $port, @_ if @_ };
578 #TODO: mon-less form? 634 #TODO: mon-less form?
579 635
580 mon $port, sub { 0 && @refs } 636 mon $port, sub { 0 && @refs }
581} 637}
582 638
583=item lnk $port1, $port2
584
585=item lnk $otherport
586
587Link two ports. This is simply a shorthand for:
588
589 mon $port1, $port2;
590 mon $port2, $port1;
591
592It means that if either one is killed abnormally, the other one gets
593killed as well.
594
595The one-argument form assumes that one port is C<$SELF>.
596
597=cut
598
599sub lnk {
600 my $port1 = shift;
601 my $port2 = @_ ? shift : $SELF || Carp::croak 'lnk: called with one argument only, but $SELF not set,';
602
603 mon $port1, $port2;
604 mon $port2, $port1;
605}
606
607=item kil $port[, @reason] 639=item kil $port[, @reason]
608 640
609Kill the specified port with the given C<@reason>. 641Kill the specified port with the given C<@reason>.
610 642
611If no C<@reason> is specified, then the port is killed "normally" (linked 643If no C<@reason> is specified, then the port is killed "normally" (linked
617Runtime errors while evaluating C<rcv> callbacks or inside C<psub> blocks 649Runtime errors while evaluating C<rcv> callbacks or inside C<psub> blocks
618will be reported as reason C<< die => $@ >>. 650will be reported as reason C<< die => $@ >>.
619 651
620Transport/communication errors are reported as C<< transport_error => 652Transport/communication errors are reported as C<< transport_error =>
621$message >>. 653$message >>.
654
655=cut
656
657=item $port = spawn $node, $initfunc[, @initdata]
658
659Creates a port on the node C<$node> (which can also be a port ID, in which
660case it's the node where that port resides).
661
662The port ID of the newly created port is return immediately, and it is
663permissible to immediately start sending messages or monitor the port.
664
665After the port has been created, the init function is
666called. This function must be a fully-qualified function name
667(e.g. C<MyApp::Chat::Server::init>). To specify a function in the main
668program, use C<::name>.
669
670If the function doesn't exist, then the node tries to C<require>
671the package, then the package above the package and so on (e.g.
672C<MyApp::Chat::Server>, C<MyApp::Chat>, C<MyApp>) until the function
673exists or it runs out of package names.
674
675The init function is then called with the newly-created port as context
676object (C<$SELF>) and the C<@initdata> values as arguments.
677
678A common idiom is to pass your own port, monitor the spawned port, and
679in the init function, monitor the original port. This two-way monitoring
680ensures that both ports get cleaned up when there is a problem.
681
682Example: spawn a chat server port on C<$othernode>.
683
684 # this node, executed from within a port context:
685 my $server = spawn $othernode, "MyApp::Chat::Server::connect", $SELF;
686 mon $server;
687
688 # init function on C<$othernode>
689 sub connect {
690 my ($srcport) = @_;
691
692 mon $srcport;
693
694 rcv $SELF, sub {
695 ...
696 };
697 }
698
699=cut
700
701sub _spawn {
702 my $port = shift;
703 my $init = shift;
704
705 local $SELF = "$NODE#$port";
706 eval {
707 &{ load_func $init }
708 };
709 _self_die if $@;
710}
711
712sub spawn(@) {
713 my ($noderef, undef) = split /#/, shift, 2;
714
715 my $id = "$RUNIQ." . $ID++;
716
717 $_[0] =~ /::/
718 or Carp::croak "spawn init function must be a fully-qualified name, caught";
719
720 ($NODE{$noderef} || add_node $noderef)
721 ->send (["", "AnyEvent::MP::_spawn" => $id, @_]);
722
723 "$noderef#$id"
724}
622 725
623=back 726=back
624 727
625=head1 NODE MESSAGES 728=head1 NODE MESSAGES
626 729
759or I<none>, there is no in-between, so monitoring single processes is 862or I<none>, there is no in-between, so monitoring single processes is
760difficult to implement. Monitoring in AEMP is more flexible than in 863difficult to implement. Monitoring in AEMP is more flexible than in
761Erlang, as one can choose between automatic kill, exit message or callback 864Erlang, as one can choose between automatic kill, exit message or callback
762on a per-process basis. 865on a per-process basis.
763 866
764=item * Erlang has different semantics for monitoring and linking, AEMP has the same. 867=item * Erlang tries to hide remote/local connections, AEMP does not.
765 868
766Monitoring in Erlang is not an indicator of process death/crashes, 869Monitoring in Erlang is not an indicator of process death/crashes,
767as linking is (except linking is unreliable in Erlang). In AEMP, the 870as linking is (except linking is unreliable in Erlang).
768semantics of monitoring and linking are identical, linking is simply 871
769two-way monitoring with automatic kill. 872In AEMP, you don't "look up" registered port names or send to named ports
873that might or might not be persistent. Instead, you normally spawn a port
874on the remote node. The init function monitors the you, and you monitor
875the remote port. Since both monitors are local to the node, they are much
876more reliable.
877
878This also saves round-trips and avoids sending messages to the wrong port
879(hard to do in Erlang).
880
881=back
882
883=head1 RATIONALE
884
885=over 4
886
887=item Why strings for ports and noderefs, why not objects?
888
889We considered "objects", but found that the actual number of methods
890thatc an be called are very low. Since port IDs and noderefs travel over
891the network frequently, the serialising/deserialising would add lots of
892overhead, as well as having to keep a proxy object.
893
894Strings can easily be printed, easily serialised etc. and need no special
895procedures to be "valid".
896
897And a a miniport consists of a single closure stored in a global hash - it
898can't become much cheaper.
899
900=item Why favour JSON, why not real serialising format such as Storable?
901
902In fact, any AnyEvent::MP node will happily accept Storable as framing
903format, but currently there is no way to make a node use Storable by
904default.
905
906The default framing protocol is JSON because a) JSON::XS is many times
907faster for small messages and b) most importantly, after years of
908experience we found that object serialisation is causing more problems
909than it gains: Just like function calls, objects simply do not travel
910easily over the network, mostly because they will always be a copy, so you
911always have to re-think your design.
912
913Keeping your messages simple, concentrating on data structures rather than
914objects, will keep your messages clean, tidy and efficient.
770 915
771=back 916=back
772 917
773=head1 SEE ALSO 918=head1 SEE ALSO
774 919

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines