[Mongrel] Shared listening sockets

Robert Mela rob at robmela.com
Tue Oct 23 12:28:32 EDT 2007

Several years back I accidentally discovered that multiple processes can 
listen on the same TCP/IP socket.  The trick of course is that all the 
processes are in the same process group, and the socket is opened by a 
shared parent.   The OS somehow was managing queuing up the various 
calls to accept() on that socket.   Since the watchdog parent / multiple 
child servers is a common, this was a workable solution on the versions 
of Linux we were using.

IIRC, the OS gracefully queued several processes' calls to accept(), 
requiring no additional synchronization.   But, even if that weren't the 
case, there is still the option of puting an acceptor in a parent and 
dispatching the client socket to available child servers.

Anyhow --

The application I wrote has a watchdog process in C that opens up a 
server socket before forking child server processes.  The children get 
passed the descriptor number for that server socket as an argument on 
their command lines.

All child server processes then enter an accept loop.   They all call 
accept() on that same, shared descriptor .   Each child, btw, opened up 
its own "private" admin socket on a port that was an offset of the main, 
shared service port ( and optionally on a different interface as well ).

Within a pool then processes are somewhat self-balancing -- a process 
only calls accept() when it's got threads available and ready to handle 
a reqeust.   Clients, or a client load balancer, don't have to keep 
track of traffic or request counts between individual server processes.  
They also don't have to try back-end app servers individually before 
finding a "thread" that's free --  if any process in a pool is 
available, it's already sitting in accept() on that shared socket (  
likely with others queued up behind it in their accept() calls).

If Mongrel's suitable as an Internet-facing front-end, then there might 
be, for many applications, no need for a load balancing proxy.   Simply 
fire up a pool of mongrels at port 80, and they'll sort it all out among 
themselves.   Even for applications requiring multiple machines a scheme 
like this would simplify load balancer proxy configurations (100 
mongrels in a pool?  No problem -- all one port!)

I'm sure the folks who wrote Mongrel thought of this and either tried it 
or rejected it beforehand for good reason.   And I had the luxury of 
coding for just one platform.   Perhaps others impose hurdles that make 
this impractical.  But even there, isn't there the Apache model of a 
parent acceptor() passing client sockets to ready children?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: rob.vcf
Type: text/x-vcard
Size: 116 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/mongrel-users/attachments/20071023/f7c43ca1/attachment.vcf 

More information about the Mongrel-users mailing list