AnyEvent-Fork-RPC

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

                This serialiser (currently the default) concatenates
                length-prefixes octet strings, and is the default. That
                means you can only pass (and return) strings containing
                character codes 0-255.

                The main advantages of this serialiser are the high speed
                and that it doesn't need another module. The main
                disadvantage is that you are very limited in what you can
                pass - only octet strings.

                Implementation:

                   (
                      sub { pack   "(w/a*)*", @_ },
                      sub { unpack "(w/a*)*", shift }
                   )

            $AnyEvent::Fork::RPC::CBOR_XS_SERIALISER - uses CBOR::XS
                This serialiser creates CBOR::XS arrays - you have to make
                sure the CBOR::XS module is installed for this serialiser to
                work. It can be beneficial for sharing when you preload the
                CBOR::XS module in a template process.

                CBOR::XS is about as fast as the octet string serialiser,
                but supports complex data structures (similar to JSON) and
                is faster than any of the other serialisers. If you have the
                CBOR::XS module available, it's the best choice.

                The encoder enables "allow_sharing" (so this serialisation
                method can encode cyclic and self-referencing data
                structures).

                Implementation:

                   use CBOR::XS ();
                   (
                      sub {    CBOR::XS::encode_cbor_sharing \@_ },
                      sub { @{ CBOR::XS::decode_cbor shift } }
                   )

            $AnyEvent::Fork::RPC::JSON_SERIALISER - uses JSON::XS or JSON
                This serialiser creates JSON arrays - you have to make sure
                the JSON module is installed for this serialiser to work. It
                can be beneficial for sharing when you preload the JSON
                module in a template process.

                JSON (with JSON::XS installed) is slower than the octet
                string serialiser, but usually much faster than Storable,
                unless big chunks of binary data need to be transferred.

                Implementation:

                   use JSON ();
                   (
                      sub {    JSON::encode_json \@_ },
                      sub { @{ JSON::decode_json shift } }
                   )

            $AnyEvent::Fork::RPC::STORABLE_SERIALISER - Storable
                This serialiser uses Storable, which means it has high
                chance of serialising just about anything you throw at it,
                at the cost of having very high overhead per operation. It
                also comes with perl. It should be used when you need to
                serialise complex data structures.

                Implementation:

                   use Storable ();
                   (
                      sub {    Storable::freeze \@_ },
                      sub { @{ Storable::thaw shift } }
                   )

            $AnyEvent::Fork::RPC::NSTORABLE_SERIALISER - portable Storable
                This serialiser also uses Storable, but uses it's "network"
                format to serialise data, which makes it possible to talk to
                different perl binaries (for example, when talking to a
                process created with AnyEvent::Fork::Remote).

                Implementation:

                   use Storable ();
                   (
                      sub {    Storable::nfreeze \@_ },
                      sub { @{ Storable::thaw shift } }
                   )

        buflen => $bytes (default: "512 - 16")
            The starting size of the read buffer for request and response
            data.

            "AnyEvent::Fork::RPC" ensures that the buffer for reeading
            request and response data is large enough for at leats aingle
            request or response, and will dynamically enlarge the buffer if
            needed.

            While this ensures that memory is not overly wasted, it
            typically leads to having to do one syscall per request, which
            can be inefficient in some cases. In such cases, it can be
            beneficient to increase the buffer size to hold more than one
            request.

        buflen_req => $bytes (default: same as "buflen")
            Overrides "buflen" for request data (as read by the forked
            process).

        buflen_res => $bytes (default: same as "buflen")
            Overrides "buflen" for response data (replies read by the parent
            process).

        See the examples section earlier in this document for some actual
        examples.

    $rpc->(..., $cb->(...))
        The RPC object returned by "AnyEvent::Fork::RPC::run" is actually a
        code reference. There are two things you can do with it: call it,
        and let it go out of scope (let it get destroyed).

        If "async" was false when $rpc was created (the default), then, if
        you call $rpc, the $function is invoked with all arguments passed to
        $rpc except the last one (the callback). When the function returns,

README  view on Meta::CPAN

    Note that these functions are typically not yet declared when code is
    compiled into the child, because the backend module is only loaded when
    you call "run", which is typically the last method you call on the fork
    object.

    Therefore, you either have to explicitly pre-load the right backend
    module or mark calls to these functions as function calls, e.g.:

       AnyEvent::Fork::RPC::event (0 => "five");
       AnyEvent::Fork::RPC::event->(0 => "five");
       &AnyEvent::Fork::RPC::flush;

    AnyEvent::Fork::RPC::event (...)
        Send an event to the parent. Events are a bit like RPC calls made by
        the child process to the parent, except that there is no notion of
        return values.

        See the examples section earlier in this document for some actual
        examples.

        Note: the event data, like any data send to the parent, might not be
        sent immediatelly but queued for later sending, so there is no
        guarantee that the event has been sent to the parent when the call
        returns - when you e.g. exit directly after calling this function,
        the parent might never receive the event. See the next function for
        a remedy.

    $success = AnyEvent::Fork::RPC::flush ()
        Synchronously wait and flush the reply data to the parent. Returns
        true on success and false otherwise (i.e. when the reply data cannot
        be written at all). Ignoring the success status is a common and
        healthy behaviour.

        Only the "async" backend does something on "flush" - the "sync"
        backend is not buffering reply data and always returns true from
        this function.

        Normally, reply data might or might not be written to the parent
        immediatelly but is buffered. This can greatly improve performance
        and efficiency, but sometimes can get in your way: for example. when
        you want to send an error message just before exiting, or when you
        want to ensure replies timely reach the parent before starting a
        long blocking operation.

        In these cases, you can call this function to flush any outstanding
        reply data to the parent. This is done blockingly, so no requests
        will be handled and no event callbacks will be called.

        For example, you could wrap your request function in a "eval" block
        and report the exception string back to the caller just before
        exiting:

           sub req {
              ...

              eval {
                 ...
              };

              if ($@) {
                 AnyEvent::RPC::event (throw => "$@");
                 AnyEvent::RPC::flush ();
                 exit;
              }

              ...
           }

  PROCESS EXIT
    If and when the child process exits depends on the backend and
    configuration. Apart from explicit exits (e.g. by calling "exit") or
    runtime conditions (uncaught exceptions, signals etc.), the backends
    exit under these conditions:

    Synchronous Backend
        The synchronous backend is very simple: when the process waits for
        another request to arrive and the writing side (usually in the
        parent) is closed, it will exit normally, i.e. as if your main
        program reached the end of the file.

        That means that if your parent process exits, the RPC process will
        usually exit as well, either because it is idle anyway, or because
        it executes a request. In the latter case, you will likely get an
        error when the RPc process tries to send the results to the parent
        (because agruably, you shouldn't exit your parent while there are
        still outstanding requests).

        The process is usually quiescent when it happens, so it should
        rarely be a problem, and "END" handlers can be used to clean up.

    Asynchronous Backend
        For the asynchronous backend, things are more complicated: Whenever
        it listens for another request by the parent, it might detect that
        the socket was closed (e.g. because the parent exited). It will sotp
        listening for new requests and instead try to write out any
        remaining data (if any) or simply check whether the socket can be
        written to. After this, the RPC process is effectively done - no new
        requests are incoming, no outstanding request data can be written
        back.

        Since chances are high that there are event watchers that the RPC
        server knows nothing about (why else would one use the async backend
        if not for the ability to register watchers?), the event loop would
        often happily continue.

        This is why the asynchronous backend explicitly calls "CORE::exit"
        when it is done (under other circumstances, such as when there is an
        I/O error and there is outstanding data to write, it will log a
        fatal message via AnyEvent::Log, also causing the program to exit).

        You can override this by specifying a function name to call via the
        "done" parameter instead.

ADVANCED TOPICS
  Choosing a backend
    So how do you decide which backend to use? Well, that's your problem to
    solve, but here are some thoughts on the matter:

    Synchronous
        The synchronous backend does not rely on any external modules (well,
        except common::sense, which works around a bug in how perl's warning



( run in 1.515 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )