--- AnyEvent-MP/MP.pm 2009/08/04 18:46:16 1.23 +++ AnyEvent-MP/MP.pm 2009/08/04 23:16:57 1.29 @@ -45,31 +45,43 @@ =item port -A port is something you can send messages to with the C function, and -you can register C handlers with. All C handlers will receive -messages they match, messages will not be queued. +A port is something you can send messages to (with the C function). + +Some ports allow you to register C handlers that can match specific +messages. All C handlers will receive messages they match, messages +will not be queued. =item port id - C -A port id is always the noderef, a hash-mark (C<#>) as separator, followed -by a port name (a printable string of unspecified format). +A port id is normaly the concatenation of a noderef, a hash-mark (C<#>) as +separator, and a port name (a printable string of unspecified format). An +exception is the the node port, whose ID is identical to it's node +reference. =item node A node is a single process containing at least one port - the node -port. You can send messages to node ports to let them create new ports, -among other things. +port. You can send messages to node ports to find existing ports or to +create new ports, among other things. -Initially, nodes are either private (single-process only) or hidden -(connected to a master node only). Only when they epxlicitly "become -public" can you send them messages from unrelated other nodes. +Nodes are either private (single-process only), slaves (connected to a +master node only) or public nodes (connectable from unrelated nodes). =item noderef - C, C, C -A noderef is a string that either uniquely identifies a given node (for -private and hidden nodes), or contains a recipe on how to reach a given +A node reference is a string that either simply identifies the node (for +private and slave nodes), or contains a recipe on how to reach a given node (for public nodes). +This recipe is simply a comma-separated list of C pairs (for +TCP/IP, other protocols might look different). + +Node references come in two flavours: resolved (containing only numerical +addresses) or unresolved (where hostnames are used instead of addresses). + +Before using an unresolved node reference in a message you first have to +resolve it. + =back =head1 VARIABLES/FUNCTIONS @@ -90,9 +102,10 @@ use base "Exporter"; -our $VERSION = '0.02'; +our $VERSION = '0.1'; our @EXPORT = qw( NODE $NODE *SELF node_of _any_ + resolve_node become_slave become_public snd rcv mon kil reg psub port @@ -117,6 +130,35 @@ Extracts and returns the noderef from a portid or a noderef. +=item $cv = resolve_node $noderef + +Takes an unresolved node reference that may contain hostnames and +abbreviated IDs, resolves all of them and returns a resolved node +reference. + +In addition to C pairs allowed in resolved noderefs, the +following forms are supported: + +=over 4 + +=item the empty string + +An empty-string component gets resolved as if the default port (4040) was +specified. + +=item naked port numbers (e.g. C<1234>) + +These are resolved by prepending the local nodename and a colon, to be +further resolved. + +=item hostnames (e.g. C, C) + +These are resolved by using AnyEvent::DNS to resolve them, optionally +looking up SRV records for the C port, if no port was +specified. + +=back + =item $SELF Contains the current port id while executing C callbacks or C @@ -247,6 +289,16 @@ mon $port, sub { 0 && @refs } } +=item lnk $port1, $port2 + +Link two ports. This is simply a shorthand for: + + mon $port1, $port2; + mon $port2, $port1; + +It means that if either one is killed abnormally, the other one gets +killed as well. + =item $local_port = port Create a new local port object that supports message matching. @@ -439,18 +491,16 @@ =over 4 -=item become_public endpoint... +=item become_public $noderef Tells the node to become a public node, i.e. reachable from other nodes. -If no arguments are given, or the first argument is C, then -AnyEvent::MP tries to bind on port C<4040> on all IP addresses that the -local nodename resolves to. - -Otherwise the first argument must be an array-reference with transport -endpoints ("ip:port", "hostname:port") or port numbers (in which case the -local nodename is used as hostname). The endpoints are all resolved and -will become the node reference. +The first argument is the (unresolved) node reference of the local node +(if missing then the empty string is used). + +It is quite common to not specify anything, in which case the local node +tries to listen on the default port, or to only specify a port number, in +which case AnyEvent::MP tries to guess the local addresses. =cut @@ -463,6 +513,8 @@ message - C<$reply[0]> is the port to reply to, C<$reply[1]> the type and the remaining arguments are simply the message data. +While other messages exist, they are not public and subject to change. + =over 4 =cut @@ -500,6 +552,93 @@ =back +=head1 AnyEvent::MP vs. Distributed Erlang + +AnyEvent::MP got lots of its ideas from distributed erlang (erlang node +== aemp node, erlang process == aemp port), so many of the documents and +programming techniques employed by erlang apply to AnyEvent::MP. Here is a +sample: + + http://www.erlang.se/doc/programming_rules.shtml + http://erlang.org/doc/getting_started/part_frame.html # chapters 3 and 4 + http://erlang.org/download/erlang-book-part1.pdf # chapters 5 and 6 + http://erlang.org/download/armstrong_thesis_2003.pdf # chapters 4 and 5 + +Despite the similarities, there are also some important differences: + +=over 4 + +=item * Node references contain the recipe on how to contact them. + +Erlang relies on special naming and DNS to work everywhere in the +same way. AEMP relies on each node knowing it's own address(es), with +convenience functionality. + +This means that AEMP requires a less tightly controlled environment at the +cost of longer node references and a slightly higher management overhead. + +=item * Erlang uses processes and a mailbox, AEMP does not queue. + +Erlang uses processes that selctively receive messages, and therefore +needs a queue. AEMP is event based, queuing messages would serve no useful +purpose. + +(But see L for a more erlang-like process model on top of AEMP). + +=item * Erlang sends are synchronous, AEMP sends are asynchronous. + +Sending messages in erlang is synchronous and blocks the process. AEMP +sends are immediate, connection establishment is handled in the +background. + +=item * Erlang can silently lose messages, AEMP cannot. + +Erlang makes few guarantees on messages delivery - messages can get lost +without any of the processes realising it (i.e. you send messages a, b, +and c, and the other side only receives messages a and c). + +AEMP guarantees correct ordering, and the guarantee that there are no +holes in the message sequence. + +=item * In erlang, processes can be declared dead and later be found to be +alive. + +In erlang it can happen that a monitored process is declared dead and +linked processes get killed, but later it turns out that the process is +still alive - and can receive messages. + +In AEMP, when port monitoring detects a port as dead, then that port will +eventually be killed - it cannot happen that a node detects a port as dead +and then later sends messages to it, finding it is still alive. + +=item * Erlang can send messages to the wrong port, AEMP does not. + +In erlang it is quite possible that a node that restarts reuses a process +ID known to other nodes for a completely different process, causing +messages destined for that process to end up in an unrelated process. + +AEMP never reuses port IDs, so old messages or old port IDs floating +around in the network will not be sent to an unrelated port. + +=item * Erlang uses unprotected connections, AEMP uses secure +authentication and can use TLS. + +AEMP can use a proven protocol - SSL/TLS - to protect connections and +securely authenticate nodes. + +=item * The AEMP protocol is optimised for both text-based and binary +communications. + +The AEMP protocol, unlike the erlang protocol, supports both +language-independent text-only protocols (good for debugging) and binary, +language-specific serialisers (e.g. Storable). + +It has also been carefully designed to be implementable in other languages +with a minimum of work while gracefully degrading fucntionality to make the +protocol simple. + +=back + =head1 SEE ALSO L.