Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: How to pass AnyEvent socket handle to pre-forked child process?

by zwon (Monsignor)
on Jan 21, 2013 at 12:05 UTC ( #1014431=note: print w/ replies, xml ) Need Help??


in reply to How to pass AnyEvent socket handle to pre-forked child process?

You can't pass filehandles between processes. Instead just let children accept connections.


Comment on Re: How to pass AnyEvent socket handle to pre-forked child process?
Re^2: How to pass AnyEvent socket handle to pre-forked child process?
by Corion (Pope) on Jan 21, 2013 at 12:51 UTC

    Actually, you can pass filehandles between processes, it's just not something that solves many problems, and there usually are better ways to accomplish the same, as you outlined already. :-)

    PPerl has code for passing around filehandles in pass_fd.c, and I wrote a replacement for that for Win32, but can't find it on RT. Maybe I forgot to open a bug for it.

    This approach still leaves systems not so close to Unix in the rain of course, so your better, and common, approach of using accept still stands.

      That's interesting, probably it's time to reread APUE, thank you
Re^2: How to pass AnyEvent socket handle to pre-forked child process?
by michaelfung (Novice) on Jan 21, 2013 at 14:34 UTC

    I can't use accept() as it is not accessible in AnyEvent.

      If whatever you receive actually is a filehandle, or even better, a socket, then you need to maybe wrap it with an AnyEvent::Handle. Looking at AnyEvent::Beanstalk, I don't see how to pass sockets around with it though.

        Thanks Corion. But I just think of a different approach: use a tcp load balancer to distribute traffic to pre-forked children listening on different ports of localhost.

      You can use accept, you just should ensure that it will not block. Make server socket non-blocking, add read watcher to it, in read callback accept all connections. Something like:

      use AnyEvent::Util qw(fh_nonblocking); ...; fh_nonblocking $srv_sock, 1; my $w = AE::io $srv_sock, 0, sub { while(accept my $cli_sock, $srv_sock) { # initialize watchers for client socket } };

        Thanks Pavel! Now I know that sockets can be shared between forked childen.

        The following skeleton worked for me:

        # parent domain ... my $server_socket = IO::Socket::INET->new( Listen => 5, ReuseAddr => 1, LocalAddr => 'a.b.c.d', LocalPort => nnnn, Blocking => 0 ) # fork n children ... # child domain: fh_nonblocking $server_socket, 1; my $w = AE::io $server_socket, 0, sub { while(accept my $client_socket, $server_socket) { # setup handlers for this new client: $handles->{$client_id} = new AnyEvent::Handle( fh => $client_socket, on_read => sub { ... }, on_error => sub { ... }, ); $handles->{$client_id}->push_write ("Child $child_no welcome client + $client_id \015\012"); ...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1014431]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2014-12-27 11:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls