On Oct 10, 2005, at 12:01 AM, Paul Querna wrote:
Brian Pane wrote:
With the batch of commits I did this weekend, the Event MPM in
the async-dev Subversion branch now does write completion
in a nonblocking manner. Once an entire response has been
generated and passed to the output filter chain, the MPM's
poller/listener thread watches the connection for writability
events. When the connection becomes writable, the poller
thread sends it to one of the worker threads, which writes
some more output.
If the content has already been generated, why add the overhead of
the context switch/sending to another thread? Can't the same event
thread do a non-blocking write?
Once it finishes writing, then yes, we do require a context-switch
to another thread to do logging/cleanup.
I am mostly thinking about downloading a 1 gig file with the
current pattern against a slow client. A non-blocking write might
only do ~64k at a time, and causing 1 gig/64k context switches,
which seems less than optimal.
If I had to choose, I'd rather do the context switches than devote a
thread (and the associated stack space) to the connection until
the writes are finished--especially if the server is delivering a
thousand 1GB files to slow clients concurrently.
However, it's probably possible to have _both_ a high ratio
of connections to threads (for scalability) and a low ratio of
context switches to megabytes delivered (for efficiency).
The Event MPM currently has to do a lot of context switching
because it detects events in one thread and processes them
in another. If we add async write completion to the
Leader/Followers MPM (or incorporate a leader/follower
thread model into Event), it should reduce the context
switches considerably.
...
- The main pollset in the Event MPM currently is sized to
hold up to one socket descriptor per worker thread. With
asynchronous keepalives and write completion, the pollset
should accommodate many descriptors per thread.
The pollset is auto-resizable. That number is just the maximum
number of events that will ever be returned by a single call to
_poll(). This number if perfect for the number of threads, since
we can never dispatch to more than the number of threads we have...
Ah, thanks. I missed that key point. It makes more sense now.
Brian