AnyEvent-Fork-RPC
view release on metacpan or search on metacpan
The other thing that can be done with the RPC object is to destroy
it. In this case, the child process will execute all remaining RPC
calls, report their results, and then exit.
See the examples section earlier in this document for some actual
examples.
CHILD PROCESS USAGE
The following function is not available in this module. They are only
available in the namespace of this module when the child is running,
without having to load any extra modules. They are part of the
child-side API of AnyEvent::Fork::RPC.
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
( run in 1.521 second using v1.01-cache-2.11-cpan-140bd7fdf52 )