AnyEvent-Fork-RPC

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

       count 2 of 2
       job 2 finished
       count 2 of 3
       count 3 of 3
       job 3 finished

    While the overall ordering isn't guaranteed, the async backend still
    guarantees that events and responses are delivered to the parent process
    in the exact same ordering as they were generated in the child process.

    And unless your system is *very* busy, it should clearly show that the
    job started last will finish first, as it has the lowest count.

    This concludes the async example. Since AnyEvent::Fork does not actually
    fork, you are free to use about any module in the child, not just
    AnyEvent, but also IO::AIO, or Tk for example.

  Example 3: Asynchronous backend with Coro
    With Coro you can create a nice asynchronous backend implementation by
    defining an rpc server function that creates a new Coro thread for every
    request that calls a function "normally", i.e. the parameters from the
    parent process are passed to it, and any return values are returned to
    the parent process, e.g.:

       package My::Arith;

       sub add {
          return $_[0] + $_[1];
       }

       sub mul {
          return $_[0] * $_[1];
       }

       sub run {
          my ($done, $func, @arg) = @_;

          Coro::async_pool {
             $done->($func->(@arg));
          };
       }

    The "run" function creates a new thread for every invocation, using the
    first argument as function name, and calls the $done callback on it's
    return values. This makes it quite natural to define the "add" and "mul"
    functions to add or multiply two numbers and return the result.

    Since this is the asynchronous backend, it's quite possible to define
    RPC function that do I/O or wait for external events - their execution
    will overlap as needed.

    The above could be used like this:

       my $rpc = AnyEvent::Fork
          ->new
          ->require ("MyWorker")
          ->AnyEvent::Fork::RPC::run ("My::Arith::run",
             on_error => ..., on_event => ..., on_destroy => ...,
          );

       $rpc->(add => 1, 3, Coro::rouse_cb); say Coro::rouse_wait;
       $rpc->(mul => 3, 2, Coro::rouse_cb); say Coro::rouse_wait;

    The "say"'s will print 4 and 6.

  Example 4: Forward AnyEvent::Log messages using "on_event"
    This partial example shows how to use the "event" function to forward
    AnyEvent::Log messages to the parent.

    For this, the parent needs to provide a suitable "on_event":

       ->AnyEvent::Fork::RPC::run (
          on_event => sub {
             if ($_[0] eq "ae_log") {
                my (undef, $level, $message) = @_;
                AE::log $level, $message;
             } else {
                # other event types
             }
          },
       )

    In the child, as early as possible, the following code should
    reconfigure AnyEvent::Log to log via "AnyEvent::Fork::RPC::event":

       $AnyEvent::Log::LOG->log_cb (sub {
          my ($timestamp, $orig_ctx, $level, $message) = @{+shift};

          if (defined &AnyEvent::Fork::RPC::event) {
             AnyEvent::Fork::RPC::event (ae_log => $level, $message);
          } else {
             warn "[$$ before init] $message\n";
          }
       });

    There is an important twist - the "AnyEvent::Fork::RPC::event" function
    is only defined when the child is fully initialised. If you redirect the
    log messages in your "init" function for example, then the "event"
    function might not yet be available. This is why the log callback checks
    whether the function is there using "defined", and only then uses it to
    log the message.

PARENT PROCESS USAGE
    This module exports nothing, and only implements a single function:

    my $rpc = AnyEvent::Fork::RPC::run $fork, $function, [key => value...]
        The traditional way to call it. But it is way cooler to call it in
        the following way:

    my $rpc = $fork->AnyEvent::Fork::RPC::run ($function, [key => value...])
        This "run" function/method can be used in place of the
        AnyEvent::Fork::run method. Just like that method, it takes over the
        AnyEvent::Fork process, but instead of calling the specified
        $function directly, it runs a server that accepts RPC calls and
        handles responses.

        It returns a function reference that can be used to call the
        function in the child process, handling serialisation and data
        transfers.

        The following key/value pairs are allowed. It is recommended to have
        at least an "on_error" or "on_event" handler set.



( run in 0.424 second using v1.01-cache-2.11-cpan-483215c6ad5 )