AnyEvent-Fork-RPC
view release on metacpan or search on metacpan
It is called very early - before the serialisers are created or the
C<$function> name is resolved into a function reference, so it could be
used to load any modules that provide the serialiser or function. It can
not, however, create events.
=item done => $function (default: C<CORE::exit>)
The function to call when the asynchronous backend detects an end of file
condition when reading from the communications socket I<and> there are no
outstanding requests. It is ignored by the synchronous backend.
By overriding this you can prolong the life of a RPC process after e.g.
the parent has exited by running the event loop in the provided function
(or simply calling it, for example, when your child process uses L<EV> you
could provide L<EV::run> as C<done> function).
Of course, in that case you are responsible for exiting at the appropriate
time and not returning from
=item async => $boolean (default: C<0>)
The default server used in the child does all I/O blockingly, and only
allows a single RPC call to execute concurrently.
Setting C<async> to a true value switches to another implementation that
uses L<AnyEvent> in the child and allows multiple concurrent RPC calls (it
does not support recursion in the event loop however, blocking condvar
calls will fail).
The actual API in the child is documented in the section that describes
the calling semantics of the returned C<$rpc> function.
If you want to pre-load the actual back-end modules to enable memory
sharing, then you should load C<AnyEvent::Fork::RPC::Sync> for
synchronous, and C<AnyEvent::Fork::RPC::Async> for asynchronous mode.
If you use a template process and want to fork both sync and async
children, then it is permissible to load both modules.
=item serialiser => $string (default: C<$AnyEvent::Fork::RPC::STRING_SERIALISER>)
All arguments, result data and event data have to be serialised to be
transferred between the processes. For this, they have to be frozen and
thawed in both parent and child processes.
By default, only octet strings can be passed between the processes,
which is reasonably fast and efficient and requires no extra modules
(the C<AnyEvent::Fork::RPC> distribution does not provide these extra
serialiser modules).
For more complicated use cases, you can provide your own freeze and thaw
functions, by specifying a string with perl source code. It's supposed to
return two code references when evaluated: the first receives a list of
perl values and must return an octet string. The second receives the octet
string and must return the original list of values.
If you need an external module for serialisation, then you can either
pre-load it into your L<AnyEvent::Fork> process, or you can add a C<use>
or C<require> statement into the serialiser string. Or both.
Here are some examples - all of them are also available as global
variables that make them easier to use.
=over 4
=item C<$AnyEvent::Fork::RPC::STRING_SERIALISER> - octet strings only
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 }
)
=item C<$AnyEvent::Fork::RPC::CBOR_XS_SERIALISER> - uses L<CBOR::XS>
This serialiser creates CBOR::XS arrays - you have to make sure the
L<CBOR::XS> module is installed for this serialiser to work. It can be
beneficial for sharing when you preload the L<CBOR::XS> module in a template
process.
L<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 L<CBOR::XS> module available, it's the
best choice.
The encoder enables C<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 } }
)
=item C<$AnyEvent::Fork::RPC::JSON_SERIALISER> - uses L<JSON::XS> or L<JSON>
This serialiser creates JSON arrays - you have to make sure the L<JSON>
module is installed for this serialiser to work. It can be beneficial for
sharing when you preload the L<JSON> module in a template process.
L<JSON> (with L<JSON::XS> installed) is slower than the octet string
serialiser, but usually much faster than L<Storable>, unless big chunks of
binary data need to be transferred.
Implementation:
use JSON ();
(
sub { JSON::encode_json \@_ },
sub { @{ JSON::decode_json shift } }
( run in 0.492 second using v1.01-cache-2.11-cpan-e1769b4cff6 )