--- AnyEvent-MP/MP.pm 2009/09/07 18:42:09 1.82 +++ AnyEvent-MP/MP.pm 2009/09/22 14:14:29 1.93 @@ -1,6 +1,6 @@ =head1 NAME -AnyEvent::MP - multi-processing/message-passing framework +AnyEvent::MP - erlang-style multi-processing/message-passing framework =head1 SYNOPSIS @@ -33,19 +33,17 @@ my $port = spawn $node, $initfunc, @initdata; # monitoring - mon $port, $cb->(@msg) # callback is invoked on death - mon $port, $otherport # kill otherport on abnormal death - mon $port, $otherport, @msg # send message on death + mon $localport, $cb->(@msg) # callback is invoked on death + mon $localport, $otherport # kill otherport on abnormal death + mon $localport, $otherport, @msg # send message on death =head1 CURRENT STATUS bin/aemp - stable. AnyEvent::MP - stable API, should work. AnyEvent::MP::Intro - explains most concepts. - AnyEvent::MP::Kernel - mostly stable. - AnyEvent::MP::Global - stable but incomplete, protocol not yet final. - -stay tuned. + AnyEvent::MP::Kernel - mostly stable API. + AnyEvent::MP::Global - stable API. =head1 DESCRIPTION @@ -85,7 +83,7 @@ (no listening ports). Private nodes cannot talk to other private nodes currently. -=item node ID - C<[a-za-Z0-9_\-.:]+> +=item node ID - C<[A-Z_][a-zA-Z0-9_\-.:]*> A node ID is a string that uniquely identifies the node within a network. Depending on the configuration used, node IDs can look like a @@ -99,20 +97,33 @@ endpoints - binds. Currently, only standard C specifications can be used, which specify TCP ports to listen on. -=item seeds - C +=item seed nodes When a node starts, it knows nothing about the network. To teach the node about the network it first has to contact some other node within the network. This node is called a seed. -Seeds are transport endpoint(s) of as many nodes as one wants. Those nodes -are expected to be long-running, and at least one of those should always -be available. When nodes run out of connections (e.g. due to a network -error), they try to re-establish connections to some seednodes again to -join the network. +Apart from the fact that other nodes know them as seed nodes and they have +to have fixed listening addresses, seed nodes are perfectly normal nodes - +any node can function as a seed node for others. + +In addition to discovering the network, seed nodes are also used to +maintain the network and to connect nodes that otherwise would have +trouble connecting. They form the backbone of an AnyEvent::MP network. + +Seed nodes are expected to be long-running, and at least one seed node +should always be available. They should also be relatively responsive - a +seed node that blocks for long periods will slow down everybody else. + +=item seeds - C -Apart from being sued for seeding, seednodes are not special in any way - -every public node can be a seednode. +Seeds are transport endpoint(s) (usually a hostname/IP address and a +TCP port) of nodes thta should be used as seed nodes. + +The nodes listening on those endpoints are expected to be long-running, +and at least one of those should always be available. When nodes run out +of connections (e.g. due to a network error), they try to re-establish +connections to some seednodes again to join the network. =back @@ -139,7 +150,7 @@ our @EXPORT = qw( NODE $NODE *SELF node_of after configure - snd rcv mon mon_guard kil reg psub spawn + snd rcv mon mon_guard kil psub spawn cal port ); @@ -218,7 +229,7 @@ =back -Example: become a distributed node using the locla node name as profile. +Example: become a distributed node using the local node name as profile. This should be the most common form of invocation for "daemon"-type nodes. configure @@ -556,6 +567,7 @@ $node->monitor ($port, $cb); defined wantarray + and $cb += 0 and AnyEvent::Util::guard { $node->unmonitor ($port, $cb) } } @@ -704,6 +716,58 @@ }; } +=item cal $port, @msg, $callback[, $timeout] + +A simple form of RPC - sends a message to the given C<$port> with the +given contents (C<@msg>), but adds a reply port to the message. + +The reply port is created temporarily just for the purpose of receiving +the reply, and will be Ced when no longer needed. + +A reply message sent to the port is passed to the C<$callback> as-is. + +If an optional time-out (in seconds) is given and it is not C, +then the callback will be called without any arguments after the time-out +elapsed and the port is Ced. + +If no time-out is given, then the local port will monitor the remote port +instead, so it eventually gets cleaned-up. + +Currently this function returns the temporary port, but this "feature" +might go in future versions unless you can make a convincing case that +this is indeed useful for something. + +=cut + +sub cal(@) { + my $timeout = ref $_[-1] ? undef : pop; + my $cb = pop; + + my $port = port { + undef $timeout; + kil $SELF; + &$cb; + }; + + if (defined $timeout) { + $timeout = AE::timer $timeout, 0, sub { + undef $timeout; + kil $port; + $cb->(); + }; + } else { + mon $_[0], sub { + kil $port; + $cb->(); + }; + } + + push @_, $port; + &snd; + + $port +} + =back =head1 AnyEvent::MP vs. Distributed Erlang