AnyEvent-MP

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

        *must* call one of the "rcv" functions to set callbacks on $SELF,
        otherwise the port might not get created.

        A common idiom is to pass a local port, immediately monitor the
        spawned port, and in the remote init function, immediately monitor
        the passed local port. This two-way monitoring ensures that both
        ports get cleaned up when there is a problem.

        "spawn" guarantees that the $initfunc has no visible effects on the
        caller before "spawn" returns (by delaying invocation when spawn is
        called for the local node).

        Example: spawn a chat server port on $othernode.

           # this node, executed from within a port context:
           my $server = spawn $othernode, "MyApp::Chat::Server::connect", $SELF;
           mon $server;

           # init function on C<$othernode>
           sub connect {
              my ($srcport) = @_;

              mon $srcport;

              rcv $SELF, sub {
                 ...
              };
           }

    after $timeout, @msg
    after $timeout, $callback
        Either sends the given message, or call the given callback, after
        the specified number of seconds.

        This is simply a utility function that comes in handy at times - the
        AnyEvent::MP author is not convinced of the wisdom of having it,
        though, so it may go away in the future.

    cal $port, @msg, $callback[, $timeout]
        A simple form of RPC - sends a message to the given $port with the
        given contents (@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 "kil"ed when no longer needed.

        A reply message sent to the port is passed to the $callback as-is.

        If an optional time-out (in seconds) is given and it is not "undef",
        then the callback will be called without any arguments after the
        time-out elapsed and the port is "kil"ed.

        If no time-out is given (or it is "undef"), 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.

DISTRIBUTED DATABASE
    AnyEvent::MP comes with a simple distributed database. The database will
    be mirrored asynchronously on all global nodes. Other nodes bind to one
    of the global nodes for their needs. Every node has a "local database"
    which contains all the values that are set locally. All local databases
    are merged together to form the global database, which can be queried.

    The database structure is that of a two-level hash - the database hash
    contains hashes which contain values, similarly to a perl hash of
    hashes, i.e.:

      $DATABASE{$family}{$subkey} = $value

    The top level hash key is called "family", and the second-level hash key
    is called "subkey" or simply "key".

    The family must be alphanumeric, i.e. start with a letter and consist of
    letters, digits, underscores and colons ("[A-Za-z][A-Za-z0-9_:]*",
    pretty much like Perl module names.

    As the family namespace is global, it is recommended to prefix family
    names with the name of the application or module using it.

    The subkeys must be non-empty strings, with no further restrictions.

    The values should preferably be strings, but other perl scalars should
    work as well (such as "undef", arrays and hashes).

    Every database entry is owned by one node - adding the same
    family/subkey combination on multiple nodes will not cause discomfort
    for AnyEvent::MP, but the result might be nondeterministic, i.e. the key
    might have different values on different nodes.

    Different subkeys in the same family can be owned by different nodes
    without problems, and in fact, this is the common method to create
    worker pools. For example, a worker port for image scaling might do
    this:

       db_set my_image_scalers => $port;

    And clients looking for an image scaler will want to get the
    "my_image_scalers" keys from time to time:

       db_keys my_image_scalers => sub {
          @ports = @{ $_[0] };
       };

    Or better yet, they want to monitor the database family, so they always
    have a reasonable up-to-date copy:

       db_mon my_image_scalers => sub {
          @ports = keys %{ $_[0] };
       };

    In general, you can set or delete single subkeys, but query and monitor
    whole families only.

    If you feel the need to monitor or query a single subkey, try giving it
    it's own family.

    $guard = db_set $family => $subkey [=> $value]
        Sets (or replaces) a key to the database - if $value is omitted,
        "undef" is used instead.

README  view on Meta::CPAN


           my $guard = db_mon AnyEvent::Fantasy::Module => sub {
              my ($family, $a, $c, $d) = @_;

              print "+$_=$family->{$_}\n" for @$a;
              print "*$_=$family->{$_}\n" for @$c;
              print "-$_=$family->{$_}\n" for @$d;
           };

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:

    *   Node IDs are arbitrary strings in AEMP.

        Erlang relies on special naming and DNS to work everywhere in the
        same way. AEMP relies on each node somehow knowing its own
        address(es) (e.g. by configuration or DNS), and possibly the
        addresses of some seed nodes, but will otherwise discover other
        nodes (and their IDs) itself.

    *   Erlang has a "remote ports are like local ports" philosophy, AEMP
        uses "local ports are like remote ports".

        The failure modes for local ports are quite different (runtime
        errors only) then for remote ports - when a local port dies, you
        *know* it dies, when a connection to another node dies, you know
        nothing about the other port.

        Erlang pretends remote ports are as reliable as local ports, even
        when they are not.

        AEMP encourages a "treat remote ports differently" philosophy, with
        local ports being the special case/exception, where transport errors
        cannot occur.

    *   Erlang uses processes and a mailbox, AEMP does not queue.

        Erlang uses processes that selectively receive messages out of
        order, and therefore needs a queue. AEMP is event based, queuing
        messages would serve no useful purpose. For the same reason the
        pattern-matching abilities of AnyEvent::MP are more limited, as
        there is little need to be able to filter messages without dequeuing
        them.

        This is not a philosophical difference, but simply stems from
        AnyEvent::MP being event-based, while Erlang is process-based.

        You can have a look at Coro::MP for a more Erlang-like process model
        on top of AEMP and Coro threads.

    *   Erlang sends are synchronous, AEMP sends are asynchronous.

        Sending messages in Erlang is synchronous and blocks the process
        until a connection has been established and the message sent (and so
        does not need a queue that can overflow). AEMP sends return
        immediately, connection establishment is handled in the background.

    *   Erlang suffers from silent message loss, AEMP does not.

        Erlang implements 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 (modulo hardware errors) correct ordering, and the
        guarantee that after one message is lost, all following ones sent to
        the same port are lost as well, until monitoring raises an error, so
        there are no silent "holes" in the message sequence.

        If you want your software to be very reliable, you have to cope with
        corrupted and even out-of-order messages in both Erlang and AEMP.
        AEMP simply tries to work better in common error cases, such as when
        a network link goes down.

    *   Erlang can send messages to the wrong port, AEMP does not.

        In Erlang it is quite likely that a node that restarts reuses an
        Erlang 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 does not reuse port IDs, so old messages or old port IDs
        floating around in the network will not be sent to an unrelated
        port.

    *   Erlang uses unprotected connections, AEMP uses secure authentication
        and can use TLS.

        AEMP can use a proven protocol - TLS - to protect connections and
        securely authenticate nodes.

    *   The AEMP protocol is optimised for both text-based and binary
        communications.

        The AEMP protocol, unlike the Erlang protocol, supports both
        programming language independent text-only protocols (good for
        debugging), and binary, language-specific serialisers (e.g.
        Storable). By default, unless TLS is used, the protocol is actually
        completely text-based.

        It has also been carefully designed to be implementable in other
        languages with a minimum of work while gracefully degrading
        functionality to make the protocol simple.

    *   AEMP has more flexible monitoring options than Erlang.

        In Erlang, you can chose to receive *all* exit signals as messages
        or *none*, there is no in-between, so monitoring single Erlang
        processes is difficult to implement.

        Monitoring in AEMP is more flexible than in Erlang, as one can
        choose between automatic kill, exit message or callback on a
        per-port basis.



( run in 1.000 second using v1.01-cache-2.11-cpan-39bf76dae61 )