Paul Querna wrote:
Paul Querna wrote: > A thread per-connection that is currently being processed.
Note that this is not the traditional 'event' model that people write huge papers about and thttpd raves about, but rather a hybrid that uses a Worker Thread todo the processing, and a single 'event' thread to handle places where we are waiting for IO. (Currently accept() and Keep Alive Requests). Perhaps it needs a different name? (eworker?)
A future direction to investigate would be to make all of the initial Header parsing be done Async, and then switch to a Worker thread to preform all the post_read hooks, handlers, and filters. I believe this could be done without breaking many 3rd party modules. (SSL could be a bigger challenge here...)
Some academics have played with this model of a event thread + worker threads. Best I can find is the Java 'SEDA: An Architecture for Highly Concurrent Server Applications'. [1]
Yeah, SEDA's model of processing "stages"--basically a succession of thread pools through
which a request passes, each with a queue in front--looks like a promising way of mixing
event-based and non-event-based processing.
Another approach I've looked at is to use Schmidt's "Reactor" design pattern, in which a central
listener thread dispatches each received event to one of a pool of worker threads. The worker
is then allowed to do arbitrarily complex processing (provided you have enough worker threads)
before deciding to tell the listener thread that it wants to wait for another event. I did some
prototyping of a Leader/Followers variant of this: have a pool of worker threads that take turns
grabbing the next event from a queue of received events. If there are no events left in the queue,
the next worker thread does a select/poll/etc (and any other idle workers block on a condition
variable). This seemed to work reasonably well in a toy test app (it was *almost* capable of
implementing HTTP/0.9, but I never had time to try 1.0 or 1.1; oh, and it depended on the
java.nio classes to do the select efficiently, so I didn't even try to commit it to
server/mpm/experimental. :-)
On a more general topic...and at the risk of igniting a distracting debate...does anybody else
out there have an interest in doing an async httpd in Java?
There are a lot of reasons *not* to do so, mostly related to all the existing httpd-2.0 modules
that wouldn't work. The things that seem appealing about trying a Java-based httpd, though,
are:
- The pool memory model at the core of httpd-1.x and -2.x isn't well suited to MPM
designs where multiple threads need to handle the same connection--possibly at the same
time, for example when a handler that's generating content needs to push output buckets
to an I/O completion thread to avoid having to block the (probably heavyweight) handler
thread or make it event-based. Garbage collection on a per-object basis would be a lot
easier.
- Modern Java implementations seem to be doing smart things from a scalability perspective,
like using kqueue/epoll/etc.
- And (minor issue) it's a lot easier to refactor things in Java than in C, and I expect that
building a good async MPM that handles dynamic content and proxying effectively will
require a lot of iterations of design trial and error.
Brian