AnyEvent-Fork-RPC
view release on metacpan or search on metacpan
their results, and then exit.
See the examples section earlier in this document for some actual
examples.
=back
=head1 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 L<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 C<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;
=over 4
=item 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.
=item $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 C<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 C<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;
}
...
}
=back
=head2 PROCESS EXIT
If and when the child process exits depends on the backend and
configuration. Apart from explicit exits (e.g. by calling C<exit>) or
runtime conditions (uncaught exceptions, signals etc.), the backends exit
under these conditions:
=over 4
=item 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 C<END> handlers can be used to clean up.
=item 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
( run in 3.358 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )