Re: InfoWorld web server shootout

Alex Belits (
Tue, 8 Jul 1997 00:55:05 -0700 (PDT)

On Mon, 7 Jul 1997, Dean Gaudet wrote:

> The thing that messes it up is supporting multiple Listen directives. If
> you do a naive select/accept loop you'll either end up starving some
> sockets (if you use blocking listeners), or you'll end up spiking the load
> (if you use non-blocking listeners) as most of the children race out of
> select, fail on accept, and run back into select. For a single listening
> socket it's much easier.

I use single listening socket and after accept() and receiving/minimal
parsing of request it either serves request by itself in the same select()
loop asyncronously using buffers and nonblicking write(), or passes
descriptors to processes that do blocking i/o. For blocking write() former
versions used fork() to create process, and it caused an overhead because
memory that should change in main process remained allocated in child thus
having a good chance to trigger copy-on-write when requests takes
relatively long time to be completed. New module design avoids that by fd
passing to processes that are even from different executable, and requests
distribution code is taken from already well working processes-modules
interface. Processes-modules interface is a bit similar to FastCGI (module
is a process, connected through pipes or sockets), but IMHO it achieves
higher performance for locally running processes. I didn't use it for
regular file i/o because until now there was no way to bypass buffering in
the main process, although now fd-passing is added to its functionality,
so I can use different modes of the same interface for "smart" modules and
"dumb" file-sending.