Cleaned up writing. Began work on Ebb::Input.
commitacea8d77681aa622a6cfd253c82310b4a038e6ce
authorRyan Dahl <ry@lakshmi.local>
Sun, 3 Feb 2008 17:42:28 +0000 (3 18:42 +0100)
committerRyan Dahl <ry@lakshmi.local>
Sun, 3 Feb 2008 17:42:28 +0000 (3 18:42 +0100)
tree3bbb13e296b95e4aa15d8c5582ee6effa654b8dc
parent863f3d2dd7a55543d19b2b25a0b17831f52aa925
Cleaned up writing. Began work on Ebb::Input.

For the time being I will not support streaming responses. Hardly any
applications use it, I think most frameworks (Rails?) don't even support it.
I think it will require some sort of ring buffer with memory pool. I would
rather worry about that when more essential features (like uploads!) are in
place.

Writing now works by having a GString attached to each client which is
appended to with each ruby Client#write call. Client#start_writing is called
when the entire response has been memcpy'd into this GString. start_writing
attaches a libev watcher to the socket to write the GString.

Between requests the GString IS NOT FREED - just reset to length zero. That
is the memory used by each client will grow to the largest file served by
Ebb. A bad thing? Not really - in real life Ebb will live behind a front-end
webserver which can serve large static files. Ebb will only be sending
dynamically generated content (which rarely is more than 100 kilobytes) or
use Sendfile headers. This means zero allocations for responses after the
first couple of requests.

There is a large performance increase with this commit.
Here are two sample measurements:

  5 kilobyte responses
    ebb (c=50,s=5 KB)  360.63 req/sec (500 completed)
    thin (c=50,s=5 KB)  288.98 req/sec (500 completed)
    evented mongrel (c=50,s=5 KB)  210.89 req/sec (500 completed)
    mongrel (c=50,s=5 KB)  71.65 req/sec (500 completed)

  50 kilobyte responses
    ebb (c=50,s=50 KB)  319.39 req/sec (500 completed)
    evented mongrel (c=50,s=50 KB)  115.48 req/sec (500 completed)
    thin (c=50,s=50 KB)  69.77 req/sec (500 completed)
    mongrel (c=50,s=50 KB)  10.94 req/sec (500 completed)

I added a Ebb::Input class which will conform to Rack's input stream
specification. It does not currently and is untested. Work will continue on
that front once I write a benchmark for uploads.
ebb.c
ebb.h
ruby_binding/benchmark/camping2.rb
ruby_binding/benchmark/server_test.rb
ruby_binding/ebb.rb
ruby_binding/ebb_ext.c
ruby_binding/test.rb