AnyEvent-MP

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN


        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.

    *   Erlang tries to hide remote/local connections, AEMP does not.

        Monitoring in Erlang is not an indicator of process death/crashes,
        in the same way as linking is (except linking is unreliable in
        Erlang).

        In AEMP, you don't "look up" registered port names or send to named
        ports that might or might not be persistent. Instead, you normally
        spawn a port on the remote node. The init function monitors you, and
        you monitor the remote port. Since both monitors are local to the
        node, they are much more reliable (no need for "spawn_link").

        This also saves round-trips and avoids sending messages to the wrong
        port (hard to do in Erlang).

RATIONALE
    Why strings for port and node IDs, why not objects?
        We considered "objects", but found that the actual number of methods
        that can be called are quite low. Since port and node IDs travel
        over the network frequently, the serialising/deserialising would add
        lots of overhead, as well as having to keep a proxy object
        everywhere.

        Strings can easily be printed, easily serialised etc. and need no
        special procedures to be "valid".

        And as a result, a port with just a default receiver consists of a
        single code reference stored in a global hash - it can't become much
        cheaper.

    Why favour JSON, why not a 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 (although all nodes will accept it).

        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 solves: 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



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