--- AnyEvent-MP/MP.pm 2009/08/14 15:31:21 1.53 +++ AnyEvent-MP/MP.pm 2009/08/27 07:12:48 1.62 @@ -87,8 +87,9 @@ which provides nodes to manage each other remotely, and to create new ports. -Nodes are either private (single-process only), slaves (connected to a -master node only) or public nodes (connectable from unrelated nodes). +Nodes are either private (single-process only), slaves (can only talk to +public nodes, but do not need an open port) or public nodes (connectable +from any other node). =item noderef - C, C, C @@ -128,9 +129,9 @@ our $VERSION = $AnyEvent::MP::Kernel::VERSION; our @EXPORT = qw( - NODE $NODE *SELF node_of _any_ + NODE $NODE *SELF node_of after resolve_node initialise_node - snd rcv mon kil reg psub spawn + snd rcv mon mon_guard kil reg psub spawn port ); @@ -182,28 +183,28 @@ C or indirectly via a profile or the nodename) must be a noderef (possibly unresolved, in which case it will be resolved). -After resolving, the node will bind itself on all endpoints and try to -connect to all additional C<$seednodes> that are specified. Seednodes are -optional and can be used to quickly bootstrap the node into an existing -network. +After resolving, the node will bind itself on all endpoints. =item slave nodes When the C<$noderef> (either as given or overriden by the config file) is the special string C, then the node will become a slave -node. Slave nodes cannot be contacted from outside and will route most of -their traffic to the master node that they attach to. +node. Slave nodes cannot be contacted from outside, and cannot talk to +each other (at least in this version of AnyEvent::MP). -At least one additional noderef is required (either by specifying it -directly or because it is part of the configuration profile): The node -will try to connect to all of them and will become a slave attached to the -first node it can successfully connect to. +Slave nodes work by creating connections to all public nodes, using the +L service. =back -This function will block until all nodes have been resolved and, for slave -nodes, until it has successfully established a connection to a master -server. +After initialising itself, the node will connect to all additional +C<$seednodes> that are specified diretcly or via a profile. Seednodes are +optional and can be used to quickly bootstrap the node into an existing +network. + +All the seednodes will also be specially marked to automatically retry +connecting to them indefinitely, so make sure that seednodes are really +reliable and up (this might also change in the future). Example: become a public node listening on the guessed noderef, or the one specified via C for the current node. This should be the most common @@ -216,11 +217,6 @@ initialise_node "slave/"; -Example: become a slave node to any of the specified master servers. This -form is also often used for commandline clients. - - initialise_node "slave/", "master1", "192.168.13.17", "mp.example.net"; - Example: become a public node, and try to contact some well-known master servers to become part of the network. @@ -350,9 +346,10 @@ =item rcv $local_port, tag => $callback->(@msg_without_tag), ... -Register callbacks to be called on messages starting with the given tag on -the given port (and return the port), or unregister it (when C<$callback> -is C<$undef>). +Register (or replace) callbacks to be called on messages starting with the +given tag on the given port (and return the port), or unregister it (when +C<$callback> is C<$undef> or missing). There can only be one callback +registered for each tag. The original message will be passed to the callback, after the first element (the tag) has been removed. The callback will use the same @@ -374,13 +371,22 @@ ... ; +Example: temporarily register a rcv callback for a tag matching some port +(e.g. for a rpc reply) and unregister it after a message was received. + + rcv $port, $otherport => sub { + my @reply = @_; + + rcv $SELF, $otherport; + }; + =cut sub rcv($@) { my $port = shift; my ($noderef, $portid) = split /#/, $port, 2; - ($NODE{$noderef} || add_node $noderef) == $NODE{""} + $NODE{$noderef} == $NODE{""} or Carp::croak "$port: rcv can only be called on local ports, caught"; while (@_) { @@ -489,6 +495,9 @@ port). After the monitoring action was invoked, further messages might get delivered again. +Note that monitoring-actions are one-shot: once released, they are removed +and will not trigger again. + In the first form (callback), the callback is simply called with any number of C<@reason> elements (no @reason means that the port was deleted "normally"). Note also that I<< the callback B never die >>, so use @@ -658,57 +667,32 @@ $_[0] =~ /::/ or Carp::croak "spawn init function must be a fully-qualified name, caught"; - ($NODE{$noderef} || add_node $noderef) - ->send (["", "AnyEvent::MP::_spawn" => $id, @_]); + snd_to_func $noderef, "AnyEvent::MP::_spawn" => $id, @_; "$noderef#$id" } -=back - -=head1 NODE MESSAGES +=item after $timeout, @msg -Nodes understand the following messages sent to them. Many of them take -arguments called C<@reply>, which will simply be used to compose a reply -message - C<$reply[0]> is the port to reply to, C<$reply[1]> the type and -the remaining arguments are simply the message data. +=item after $timeout, $callback -While other messages exist, they are not public and subject to change. +Either sends the given message, or call the given callback, after the +specified number of seconds. -=over 4 +This is simply a utility function that come sin handy at times. =cut -=item lookup => $name, @reply +sub after($@) { + my ($timeout, @action) = @_; -Replies with the port ID of the specified well-known port, or C. - -=item devnull => ... - -Generic data sink/CPU heat conversion. - -=item relay => $port, @msg - -Simply forwards the message to the given port. - -=item eval => $string[ @reply] - -Evaluates the given string. If C<@reply> is given, then a message of the -form C<@reply, $@, @evalres> is sent. - -Example: crash another node. - - snd $othernode, eval => "exit"; - -=item time => @reply - -Replies the the current node time to C<@reply>. - -Example: tell the current node to send the current time to C<$myport> in a -C message. - - snd $NODE, time => $myport, timereply => 1, 2; - # => snd $myport, timereply => 1, 2,