--- AnyEvent-MP/MP.pm 2009/08/13 01:16:24 1.45 +++ AnyEvent-MP/MP.pm 2009/08/13 15:29:58 1.49 @@ -12,6 +12,11 @@ $SELF # receiving/own port id in rcv callbacks + # initialise the node so it can send/receive messages + initialise_node; # -OR- + initialise_node "localhost:4040"; # -OR- + initialise_node "slave/", "localhost:4040" + # ports are message endpoints # sending messages @@ -19,22 +24,22 @@ snd $port, @msg; snd @msg_with_first_element_being_a_port; - # miniports + # creating/using miniports my $miniport = port { my @msg = @_; 0 }; - # full ports + # creating/using full ports my $port = port; rcv $port, smartmatch => $cb->(@msg); rcv $port, ping => sub { snd $_[0], "pong"; 0 }; rcv $port, pong => sub { warn "pong received\n"; 0 }; - # remote ports - my $port = spawn $node, $initfunc, @initdata; - # more, smarter, matches (_any_ is exported by this module) rcv $port, [child_died => $pid] => sub { ... rcv $port, [_any_, _any_, 3] => sub { .. $_[2] is 3 + # create a port on another node + my $port = spawn $node, $initfunc, @initdata; + # monitoring mon $port, $cb->(@msg) # callback is invoked on death mon $port, $otherport # kill otherport on abnormal death @@ -165,7 +170,14 @@ This function initialises a node - it must be called exactly once (or never) before calling other AnyEvent::MP functions. -All arguments are noderefs, which can be either resolved or unresolved. +All arguments (optionally except for the first) are noderefs, which can be +either resolved or unresolved. + +The first argument will be looked up in the configuration database first +(if it is C then the current nodename will be used instead) to find +the relevant configuration profile (see L). If none is found then +the default configuration is used. The configuration supplies additional +seed/master nodes and can override the actual noderef. There are two types of networked nodes, public nodes and slave nodes: @@ -173,23 +185,26 @@ =item public nodes -For public nodes, C<$noderef> must either be a (possibly unresolved) -noderef, in which case it will be resolved, or C (or missing), in -which case the noderef will be guessed. - -Afterwards, 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. +For public nodes, C<$noderef> (supplied either directly to +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. =item slave nodes -When the C<$noderef> 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. - -At least one additional noderef is required: 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. +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. + +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. =back @@ -197,10 +212,22 @@ nodes, until it has successfully established a connection to a master server. -Example: become a public node listening on the default node. +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 +form of invocation for "daemon"-type nodes. initialise_node; +Example: become a slave node to any of the the seednodes specified via +C. This form is often used for commandline clients. + + 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. @@ -212,11 +239,7 @@ Example: become a public node, only visible on localhost port 4044. - initialise_node "locahost:4044"; - -Example: become a slave node to any of the specified master servers. - - initialise_node "slave/", "master1", "192.168.13.17", "mp.example.net"; + initialise_node "localhost:4044"; =item $cv = resolve_node $noderef @@ -857,6 +880,41 @@ =back +=head1 RATIONALE + +=over 4 + +=item Why strings for ports and noderefs, why not objects? + +We considered "objects", but found that the actual number of methods +thatc an be called are very low. Since port IDs and noderefs travel over +the network frequently, the serialising/deserialising would add lots of +overhead, as well as having to keep a proxy object. + +Strings can easily be printed, easily serialised etc. and need no special +procedures to be "valid". + +And a a miniport consists of a single closure stored in a global hash - it +can't become much cheaper. + +=item Why favour JSON, why not real serialising format such as Storable? + +In fact, any AnyEvent::MP node will happily accept Storable as framing +format, but currently there is no way to make a node use Storable by +default. + +The default framing protocol is JSON because a) JSON::XS is many times +faster for small messages and b) most importantly, after years of +experience we found that object serialisation is causing more problems +than it gains: Just like function calls, objects simply do not travel +easily over the network, mostly because they will always be a copy, so you +always have to re-think your design. + +Keeping your messages simple, concentrating on data structures rather than +objects, will keep your messages clean, tidy and efficient. + +=back + =head1 SEE ALSO L.