ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Fork-RPC/RPC.pm
(Generate patch)

Comparing AnyEvent-Fork-RPC/RPC.pm (file contents):
Revision 1.3 by root, Wed Apr 17 17:16:48 2013 UTC vs.
Revision 1.13 by root, Thu Apr 18 11:11:26 2013 UTC

2 2
3AnyEvent::Fork::RPC - simple RPC extension for AnyEvent::Fork 3AnyEvent::Fork::RPC - simple RPC extension for AnyEvent::Fork
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use AnyEvent::Fork;
8 use AnyEvent::Fork::RPC; 7 use AnyEvent::Fork::RPC;
8 # use AnyEvent::Fork is not needed
9 9
10 my $rpc = AnyEvent::Fork 10 my $rpc = AnyEvent::Fork
11 ->new 11 ->new
12 ->require ("MyModule") 12 ->require ("MyModule")
13 ->AnyEvent::Fork::RPC::run ( 13 ->AnyEvent::Fork::RPC::run (
34concurrently in the child, using AnyEvent. 34concurrently in the child, using AnyEvent.
35 35
36It also implements an asynchronous event mechanism from the child to the 36It also implements an asynchronous event mechanism from the child to the
37parent, that could be used for progress indications or other information. 37parent, that could be used for progress indications or other information.
38 38
39Loading this module also always loads L<AnyEvent::Fork>, so you can make a
40separate C<use AnyEvent::Fork> if you wish, but you don't have to.
41
42=head1 EXAMPLES
43
44=head2 Example 1: Synchronous Backend
45
46Here is a simple example that implements a backend that executes C<unlink>
47and C<rmdir> calls, and reports their status back. It also reports the
48number of requests it has processed every three requests, which is clearly
49silly, but illustrates the use of events.
50
51First the parent process:
52
53 use AnyEvent;
54 use AnyEvent::Fork::RPC;
55
56 my $done = AE::cv;
57
58 my $rpc = AnyEvent::Fork
59 ->new
60 ->require ("MyWorker")
61 ->AnyEvent::Fork::RPC::run ("MyWorker::run",
62 on_error => sub { warn "FATAL: $_[0]"; exit 1 },
63 on_event => sub { warn "$_[0] requests handled\n" },
64 on_destroy => $done,
65 );
66
67 for my $id (1..6) {
68 $rpc->(rmdir => "/tmp/somepath/$id", sub {
69 $_[0]
70 or warn "/tmp/somepath/$id: $_[1]\n";
71 });
72 }
73
74 undef $rpc;
75
76 $done->recv;
77
78The parent creates the process, queues a few rmdir's. It then forgets
79about the C<$rpc> object, so that the child exits after it has handled the
80requests, and then it waits till the requests have been handled.
81
82The child is implemented using a separate module, C<MyWorker>, shown here:
83
84 package MyWorker;
85
86 my $count;
87
88 sub run {
89 my ($cmd, $path) = @_;
90
91 AnyEvent::Fork::RPC::event ($count)
92 unless ++$count % 3;
93
94 my $status = $cmd eq "rmdir" ? rmdir $path
95 : $cmd eq "unlink" ? unlink $path
96 : die "fatal error, illegal command '$cmd'";
97
98 $status or (0, "$!")
99 }
100
101 1
102
103The C<run> function first sends a "progress" event every three calls, and
104then executes C<rmdir> or C<unlink>, depending on the first parameter (or
105dies with a fatal error - obviously, you must never let this happen :).
106
107Eventually it returns the status value true if the command was successful,
108or the status value 0 and the stringified error message.
109
110On my system, running the first code fragment with the given
111F<MyWorker.pm> in the current directory yields:
112
113 /tmp/somepath/1: No such file or directory
114 /tmp/somepath/2: No such file or directory
115 3 requests handled
116 /tmp/somepath/3: No such file or directory
117 /tmp/somepath/4: No such file or directory
118 /tmp/somepath/5: No such file or directory
119 6 requests handled
120 /tmp/somepath/6: No such file or directory
121
122Obviously, none of the directories I am trying to delete even exist. Also,
123the events and responses are processed in exactly the same order as
124they were created in the child, which is true for both synchronous and
125asynchronous backends.
126
127Note that the parentheses in the call to C<AnyEvent::Fork::RPC::event> are
128not optional. That is because the function isn't defined when the code is
129compiled. You can make sure it is visible by pre-loading the correct
130backend module in the call to C<require>:
131
132 ->require ("AnyEvent::Fork::RPC::Sync", "MyWorker")
133
134Since the backend module declares the C<event> function, loading it first
135ensures that perl will correctly interpret calls to it.
136
137And as a final remark, there is a fine module on CPAN that can
138asynchronously C<rmdir> and C<unlink> and a lot more, and more efficiently
139than this example, namely L<IO::AIO>.
140
141=head3 Example 1a: the same with the asynchronous backend
142
143This example only shows what needs to be changed to use the async backend
144instead. Doing this is not very useful, the purpose of this example is
145to show the minimum amount of change that is required to go from the
146synchronous to the asynchronous backend.
147
148To use the async backend in the previous example, you need to add the
149C<async> parameter to the C<AnyEvent::Fork::RPC::run> call:
150
151 ->AnyEvent::Fork::RPC::run ("MyWorker::run",
152 async => 1,
153 ...
154
155And since the function call protocol is now changed, you need to adopt
156C<MyWorker::run> to the async API.
157
158First, you need to accept the extra initial C<$done> callback:
159
160 sub run {
161 my ($done, $cmd, $path) = @_;
162
163And since a response is now generated when C<$done> is called, as opposed
164to when the function returns, we need to call the C<$done> function with
165the status:
166
167 $done->($status or (0, "$!"));
168
169A few remarks are in order. First, it's quite pointless to use the async
170backend for this example - but it I<is> possible. Second, you can call
171C<$done> before or after returning from the function. Third, having both
172returned from the function and having called the C<$done> callback, the
173child process may exit at any time, so you should call C<$done> only when
174you really I<are> done.
175
176=head2 Example 2: Asynchronous Backend
177
178This example implements multiple count-downs in the child, using
179L<AnyEvent> timers. While this is a bit silly (one could use timers in te
180parent just as well), it illustrates the ability to use AnyEvent in the
181child and the fact that responses can arrive in a different order then the
182requests.
183
184It also shows how to embed the actual child code into a C<__DATA__>
185section, so it doesn't need any external files at all.
186
187And when your parent process is often busy, and you have stricter timing
188requirements, then running timers in a child process suddenly doesn't look
189so silly anymore.
190
191Without further ado, here is the code:
192
193 use AnyEvent;
194 use AnyEvent::Fork::RPC;
195
196 my $done = AE::cv;
197
198 my $rpc = AnyEvent::Fork
199 ->new
200 ->require ("AnyEvent::Fork::RPC::Async")
201 ->eval (do { local $/; <DATA> })
202 ->AnyEvent::Fork::RPC::run ("run",
203 async => 1,
204 on_error => sub { warn "FATAL: $_[0]"; exit 1 },
205 on_event => sub { print $_[0] },
206 on_destroy => $done,
207 );
208
209 for my $count (3, 2, 1) {
210 $rpc->($count, sub {
211 warn "job $count finished\n";
212 });
213 }
214
215 undef $rpc;
216
217 $done->recv;
218
219 __DATA__
220
221 # this ends up in main, as we don't use a package declaration
222
223 use AnyEvent;
224
225 sub run {
226 my ($done, $count) = @_;
227
228 my $n;
229
230 AnyEvent::Fork::RPC::event "starting to count up to $count\n";
231
232 my $w; $w = AE::timer 1, 1, sub {
233 ++$n;
234
235 AnyEvent::Fork::RPC::event "count $n of $count\n";
236
237 if ($n == $count) {
238 undef $w;
239 $done->();
240 }
241 };
242 }
243
244The parent part (the one before the C<__DATA__> section) isn't very
245different from the earlier examples. It sets async mode, preloads
246the backend module (so the C<AnyEvent::Fork::RPC::event> function is
247declared), uses a slightly different C<on_event> handler (which we use
248simply for logging purposes) and then, instead of loading a module with
249the actual worker code, it C<eval>'s the code from the data section in the
250child process.
251
252It then starts three countdowns, from 3 to 1 seconds downwards, destroys
253the rpc object so the example finishes eventually, and then just waits for
254the stuff to trickle in.
255
256The worker code uses the event function to log some progress messages, but
257mostly just creates a recurring one-second timer.
258
259The timer callback increments a counter, logs a message, and eventually,
260when the count has been reached, calls the finish callback.
261
262On my system, this results in the following output. Since all timers fire
263at roughly the same time, the actual order isn't guaranteed, but the order
264shown is very likely what you would get, too.
265
266 starting to count up to 3
267 starting to count up to 2
268 starting to count up to 1
269 count 1 of 3
270 count 1 of 2
271 count 1 of 1
272 job 1 finished
273 count 2 of 2
274 job 2 finished
275 count 2 of 3
276 count 3 of 3
277 job 3 finished
278
279While the overall ordering isn't guaranteed, the async backend still
280guarantees that events and responses are delivered to the parent process
281in the exact same ordering as they were generated in the child process.
282
283And unless your system is I<very> busy, it should clearly show that the
284job started last will finish first, as it has the lowest count.
285
286This concludes the async example. Since L<AnyEvent::Fork> does not
287actually fork, you are free to use about any module in the child, not just
288L<AnyEvent>, but also L<IO::AIO>, or L<Tk> for example.
289
39=head1 PARENT PROCESS USAGE 290=head1 PARENT PROCESS USAGE
40 291
41This module exports nothing, and only implements a single function: 292This module exports nothing, and only implements a single function:
42 293
43=over 4 294=over 4
50 301
51use Errno (); 302use Errno ();
52use Guard (); 303use Guard ();
53 304
54use AnyEvent; 305use AnyEvent;
55#use AnyEvent::Fork; 306use AnyEvent::Fork; # we don't actually depend on it, this is for convenience
56 307
57our $VERSION = 0.1; 308our $VERSION = 0.1;
58 309
59=item my $rpc = AnyEvent::Fork::RPC::run $fork, $function, [key => value...] 310=item my $rpc = AnyEvent::Fork::RPC::run $fork, $function, [key => value...]
60 311
92Called for every call to the C<AnyEvent::Fork::RPC::event> function in the 343Called for every call to the C<AnyEvent::Fork::RPC::event> function in the
93child, with the arguments of that function passed to the callback. 344child, with the arguments of that function passed to the callback.
94 345
95Also called on errors when no C<on_error> handler is provided. 346Also called on errors when no C<on_error> handler is provided.
96 347
348=item on_destroy => $cb->()
349
350Called when the C<$rpc> object has been destroyed and all requests have
351been successfully handled. This is useful when you queue some requests and
352want the child to go away after it has handled them. The problem is that
353the parent must not exit either until all requests have been handled, and
354this can be accomplished by waiting for this callback.
355
97=item init => $function (default none) 356=item init => $function (default none)
98 357
99When specified (by name), this function is called in the child as the very 358When specified (by name), this function is called in the child as the very
100first thing when taking over the process, with all the arguments normally 359first thing when taking over the process, with all the arguments normally
101passed to the C<AnyEvent::Fork::run> function, except the communications 360passed to the C<AnyEvent::Fork::run> function, except the communications
102socket. 361socket.
103 362
104It can be used to do one-time things in the child such as storing passed 363It can be used to do one-time things in the child such as storing passed
105parameters or opening database connections. 364parameters or opening database connections.
106 365
366It is called very early - before the serialisers are created or the
367C<$function> name is resolved into a function reference, so it could be
368used to load any modules that provide the serialiser or function. It can
369not, however, create events.
370
107=item async => $boolean (default: 0) 371=item async => $boolean (default: 0)
108 372
109The default server used in the child does all I/O blockingly, and only 373The default server used in the child does all I/O blockingly, and only
110allows a single RPC call to execute concurrently. 374allows a single RPC call to execute concurrently.
111 375
116the calling semantics of the returned C<$rpc> function. 380the calling semantics of the returned C<$rpc> function.
117 381
118If you want to pre-load the actual back-end modules to enable memory 382If you want to pre-load the actual back-end modules to enable memory
119sharing, then you should load C<AnyEvent::Fork::RPC::Sync> for 383sharing, then you should load C<AnyEvent::Fork::RPC::Sync> for
120synchronous, and C<AnyEvent::Fork::RPC::Async> for asynchronous mode. 384synchronous, and C<AnyEvent::Fork::RPC::Async> for asynchronous mode.
385
386If you use a template process and want to fork both sync and async
387children, then it is permissible to load both modules.
121 388
122=item serialiser => $string (default: '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })') 389=item serialiser => $string (default: '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })')
123 390
124All arguments, result data and event data have to be serialised to be 391All arguments, result data and event data have to be serialised to be
125transferred between the processes. For this, they have to be frozen and 392transferred between the processes. For this, they have to be frozen and
138pre-load it into your L<AnyEvent::Fork> process, or you can add a C<use> 405pre-load it into your L<AnyEvent::Fork> process, or you can add a C<use>
139or C<require> statement into the serialiser string. Or both. 406or C<require> statement into the serialiser string. Or both.
140 407
141=back 408=back
142 409
410See the examples section earlier in this document for some actual
411examples.
412
143=cut 413=cut
144 414
145our $STRING_SERIALISER = '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })'; 415our $STRING_SERIALISER = '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })';
146
147# ideally, we want (SvLEN - SvCUR) || 1024 or somesuch...
148sub rlen($) { ($_[0] < 384 ? 512 + 16 : 2 << int +(log $_[0] + 512) / log 2) - $_[0] - 16 }
149 416
150sub run { 417sub run {
151 my ($self, $function, %arg) = @_; 418 my ($self, $function, %arg) = @_;
152 419
153 my $serialiser = delete $arg{serialiser} || $STRING_SERIALISER; 420 my $serialiser = delete $arg{serialiser} || $STRING_SERIALISER;
154 my $on_event = delete $arg{on_event}; 421 my $on_event = delete $arg{on_event};
155 my $on_error = delete $arg{on_error}; 422 my $on_error = delete $arg{on_error};
423 my $on_destroy = delete $arg{on_destroy};
156 424
157 # default for on_error is to on_event, if specified 425 # default for on_error is to on_event, if specified
158 $on_error ||= $on_event 426 $on_error ||= $on_event
159 ? sub { $on_event->(error => shift) } 427 ? sub { $on_event->(error => shift) }
160 : sub { die "AnyEvent::Fork::RPC: uncaught error: $_[0].\n" }; 428 : sub { die "AnyEvent::Fork::RPC: uncaught error: $_[0].\n" };
162 # default for on_event is to raise an error 430 # default for on_event is to raise an error
163 $on_event ||= sub { $on_error->("event received, but no on_event handler") }; 431 $on_event ||= sub { $on_error->("event received, but no on_event handler") };
164 432
165 my ($f, $t) = eval $serialiser; die $@ if $@; 433 my ($f, $t) = eval $serialiser; die $@ if $@;
166 434
167 my (@rcb, $fh, $shutdown, $wbuf, $ww, $rbuf, $rw); 435 my (@rcb, %rcb, $fh, $shutdown, $wbuf, $ww);
436 my ($rlen, $rbuf, $rw) = 512 - 16;
168 437
169 my $wcb = sub { 438 my $wcb = sub {
170 my $len = syswrite $fh, $wbuf; 439 my $len = syswrite $fh, $wbuf;
171 440
172 if (!defined $len) { 441 unless (defined $len) {
173 if ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) { 442 if ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) {
174 undef $rw; undef $ww; # it ends here 443 undef $rw; undef $ww; # it ends here
175 $on_error->("$!"); 444 $on_error->("$!");
176 } 445 }
177 } 446 }
188 457
189 $self->require ($module) 458 $self->require ($module)
190 ->send_arg ($function, $arg{init}, $serialiser) 459 ->send_arg ($function, $arg{init}, $serialiser)
191 ->run ("$module\::run", sub { 460 ->run ("$module\::run", sub {
192 $fh = shift; 461 $fh = shift;
462
463 my ($id, $len);
193 $rw = AE::io $fh, 0, sub { 464 $rw = AE::io $fh, 0, sub {
465 $rlen = $rlen * 2 + 16 if $rlen - 128 < length $rbuf;
194 my $len = sysread $fh, $rbuf, rlen length $rbuf, length $rbuf; 466 $len = sysread $fh, $rbuf, $rlen - length $rbuf, length $rbuf;
195 467
196 if ($len) { 468 if ($len) {
197 while (5 <= length $rbuf) { 469 while (8 <= length $rbuf) {
198 $len = unpack "L", $rbuf; 470 ($id, $len) = unpack "LL", $rbuf;
199 4 + $len <= length $rbuf 471 8 + $len <= length $rbuf
200 or last; 472 or last;
201 473
202 my @r = $t->(substr $rbuf, 4, $len); 474 my @r = $t->(substr $rbuf, 8, $len);
203 substr $rbuf, 0, $len + 4, ""; 475 substr $rbuf, 0, 8 + $len, "";
476
477 if ($id) {
478 if (@rcb) {
479 (shift @rcb)->(@r);
480 } elsif (my $cb = delete $rcb{$id}) {
481 $cb->(@r);
482 } else {
483 undef $rw; undef $ww;
484 $on_error->("unexpected data from child");
204 485 }
205 if (pop @r) { 486 } else {
206 $on_event->(@r); 487 $on_event->(@r);
207 } elsif (@rcb) {
208 (shift @rcb)->(@r);
209 } else {
210 undef $rw; undef $ww;
211 $on_error->("unexpected data from child");
212 } 488 }
213 } 489 }
214 } elsif (defined $len) { 490 } elsif (defined $len) {
215 undef $rw; undef $ww; # it ends here 491 undef $rw; undef $ww; # it ends here
492
493 if (@rcb || %rcb) {
216 $on_error->("unexpected eof") 494 $on_error->("unexpected eof");
217 if @rcb; 495 } else {
496 $on_destroy->();
497 }
218 } elsif ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) { 498 } elsif ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) {
219 undef $rw; undef $ww; # it ends here 499 undef $rw; undef $ww; # it ends here
220 $on_error->("read: $!"); 500 $on_error->("read: $!");
221 } 501 }
222 }; 502 };
227 my $guard = Guard::guard { 507 my $guard = Guard::guard {
228 $shutdown = 1; 508 $shutdown = 1;
229 $ww ||= $fh && AE::io $fh, 1, $wcb; 509 $ww ||= $fh && AE::io $fh, 1, $wcb;
230 }; 510 };
231 511
512 my $id;
513
514 $arg{async}
232 sub { 515 ? sub {
233 push @rcb, pop; 516 $id = ($id == 0xffffffff ? 0 : $id) + 1;
517 $id = ($id == 0xffffffff ? 0 : $id) + 1 while exists $rcb{$id}; # rarely loops
234 518
519 $rcb{$id} = pop;
520
235 $guard; # keep it alive 521 $guard; # keep it alive
236 522
237 $wbuf .= pack "L/a*", &$f; 523 $wbuf .= pack "LL/a*", $id, &$f;
238 $ww ||= $fh && AE::io $fh, 1, $wcb; 524 $ww ||= $fh && AE::io $fh, 1, $wcb;
239 } 525 }
526 : sub {
527 push @rcb, pop;
528
529 $guard; # keep it alive
530
531 $wbuf .= pack "L/a*", &$f;
532 $ww ||= $fh && AE::io $fh, 1, $wcb;
533 }
240} 534}
241 535
536=item $rpc->(..., $cb->(...))
537
538The RPC object returned by C<AnyEvent::Fork::RPC::run> is actually a code
539reference. There are two things you can do with it: call it, and let it go
540out of scope (let it get destroyed).
541
542If C<async> was false when C<$rpc> was created (the default), then, if you
543call C<$rpc>, the C<$function> is invoked with all arguments passed to
544C<$rpc> except the last one (the callback). When the function returns, the
545callback will be invoked with all the return values.
546
547If C<async> was true, then the C<$function> receives an additional
548initial argument, the result callback. In this case, returning from
549C<$function> does nothing - the function only counts as "done" when the
550result callback is called, and any arguments passed to it are considered
551the return values. This makes it possible to "return" from event handlers
552or e.g. Coro threads.
553
554The other thing that can be done with the RPC object is to destroy it. In
555this case, the child process will execute all remaining RPC calls, report
556their results, and then exit.
557
558See the examples section earlier in this document for some actual
559examples.
560
242=back 561=back
243 562
244=head1 CHILD PROCESS USAGE 563=head1 CHILD PROCESS USAGE
245 564
246These functions are not available in this module. They are only available 565The following function is not available in this module. They are only
247in the namespace of this module when the child is running, without 566available in the namespace of this module when the child is running,
248having to load any extra module. They are part of the child-side API of 567without having to load any extra modules. They are part of the child-side
249L<AnyEvent::Fork::RPC>. 568API of L<AnyEvent::Fork::RPC>.
250 569
251=over 4 570=over 4
252 571
253=item AnyEvent::Fork::RPC::event ... 572=item AnyEvent::Fork::RPC::event ...
254 573
255Send an event to the parent. Events are a bit like RPC calls made by the 574Send an event to the parent. Events are a bit like RPC calls made by the
256child process to the parent, except that there is no notion of return 575child process to the parent, except that there is no notion of return
257values. 576values.
258 577
578See the examples section earlier in this document for some actual
579examples.
580
259=back 581=back
582
583=head1 ADVANCED TOPICS
584
585=head2 Choosing a backend
586
587So how do you decide which backend to use? Well, that's your problem to
588solve, but here are some thoughts on the matter:
589
590=over 4
591
592=item Synchronous
593
594The synchronous backend does not rely on any external modules (well,
595except L<common::sense>, which works around a bug in how perl's warning
596system works). This keeps the process very small, for example, on my
597system, an empty perl interpreter uses 1492kB RSS, which becomes 2020kB
598after C<use warnings; use strict> (for people who grew up with C64s around
599them this is probably shocking every single time they see it). The worker
600process in the first example in this document uses 1792kB.
601
602Since the calls are done synchronously, slow jobs will keep newer jobs
603from executing.
604
605The synchronous backend also has no overhead due to running an event loop
606- reading requests is therefore very efficient, while writing responses is
607less so, as every response results in a write syscall.
608
609If the parent process is busy and a bit slow reading responses, the child
610waits instead of processing further requests. This also limits the amount
611of memory needed for buffering, as never more than one response has to be
612buffered.
613
614The API in the child is simple - you just have to define a function that
615does something and returns something.
616
617It's hard to use modules or code that relies on an event loop, as the
618child cannot execute anything while it waits for more input.
619
620=item Asynchronous
621
622The asynchronous backend relies on L<AnyEvent>, which tries to be small,
623but still comes at a price: On my system, the worker from example 1a uses
6243420kB RSS (for L<AnyEvent>, which loads L<EV>, which needs L<XSLoader>
625which in turn loads a lot of other modules such as L<warnings>, L<strict>,
626L<vars>, L<Exporter>...).
627
628It batches requests and responses reasonably efficiently, doing only as
629few reads and writes as needed, but needs to poll for events via the event
630loop.
631
632Responses are queued when the parent process is busy. This means the child
633can continue to execute any queued requests. It also means that a child
634might queue a lot of responses in memory when it generates them and the
635parent process is slow accepting them.
636
637The API is not a straightforward RPC pattern - you have to call a
638"done" callback to pass return values and signal completion. Also, more
639importantly, the API starts jobs as fast as possible - when 1000 jobs
640are queued and the jobs are slow, they will all run concurrently. The
641child must implement some queueing/limiting mechanism if this causes
642problems. Alternatively, the parent could limit the amount of rpc calls
643that are outstanding.
644
645Using event-based modules such as L<IO::AIO>, L<Gtk2>, L<Tk> and so on is
646easy.
647
648=back
649
650=head2 Passing file descriptors
651
652Unlike L<AnyEvent::Fork>, this module has no in-built file handle or file
653descriptor passing abilities.
654
655The reason is that passing file descriptors is extraordinary tricky
656business, and conflicts with efficient batching of messages.
657
658There still is a method you can use: Create a
659C<AnyEvent::Util::portable_socketpair> and C<send_fh> one half of it to
660the process before you pass control to C<AnyEvent::Fork::RPC::run>.
661
662Whenever you want to pass a file descriptor, send an rpc request to the
663child process (so it expects the descriptor), then send it over the other
664half of the socketpair. The child should fetch the descriptor from the
665half it has passed earlier.
666
667Here is some (untested) pseudocode to that effect:
668
669 use AnyEvent::Util;
670 use AnyEvent::Fork::RPC;
671 use IO::FDPass;
672
673 my ($s1, $s2) = AnyEvent::Util::portable_socketpair;
674
675 my $rpc = AnyEvent::Fork
676 ->new
677 ->send_fh ($s2)
678 ->require ("MyWorker")
679 ->AnyEvent::Fork::RPC::run ("MyWorker::run"
680 init => "MyWorker::init",
681 );
682
683 undef $s2; # no need to keep it around
684
685 # pass an fd
686 $rpc->("i'll send some fd now, please expect it!", my $cv = AE::cv);
687
688 IO::FDPass fileno $s1, fileno $handle_to_pass;
689
690 $cv->recv;
691
692The MyWorker module could look like this:
693
694 package MyWorker;
695
696 use IO::FDPass;
697
698 my $s2;
699
700 sub init {
701 $s2 = $_[0];
702 }
703
704 sub run {
705 if ($_[0] eq "i'll send some fd now, please expect it!") {
706 my $fd = IO::FDPass::recv fileno $s2;
707 ...
708 }
709 }
710
711Of course, this might be blocking if you pass a lot of file descriptors,
712so you might want to look into L<AnyEvent::FDpasser> which can handle the
713gory details.
260 714
261=head1 SEE ALSO 715=head1 SEE ALSO
262 716
263L<AnyEvent::Fork> (to create the processes in the first place), 717L<AnyEvent::Fork> (to create the processes in the first place),
264L<AnyEvent::Fork::Pool> (to manage whole pools of processes). 718L<AnyEvent::Fork::Pool> (to manage whole pools of processes).

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines