The current Rack spec requires rewindability, but I think the
requirement will go away for Rack 2.0
> For Passenger and Mongrel, this means a temp file is created for the request
> (at least for requests as big as those I am dealing with).
>
> Now, my question is, does Rack wait until all data from the client has been
> read to a tempfile before passing on control to the Rack app (in this case,
> Rails)? Or does it pass on control directly, and block if the application
> reads data faster than the client is sending it?
It depends on the Rack webserver. I can confirm Mongrel waits
until everthing is sent.
Disclaimer: I'm the BFDL for both Unicorn and Rainbows!
Both Unicorn[1] and Rainbows![3] can pass control directly and
block inside the app if the app is faster than the client.
Unicorn reads off the socket as data comes in and "tee"'s off the
input to a temporary file for rewindability. However, you can disable
the temporary file backing store by setting the
"rewindable_input false" option in the Unicorn config file[2].
Setting "rewindable_input false" violates the Rack spec, but can save
you a lot of filesystem I/O if you handle large files.
Unless all your clients are fast (on the same LAN), Unicorn requires
nginx in front of it and nginx reads everything before sending it to
Unicorn), so "rewindable_input false" doesn't do much, however...
Rainbows! is based on Unicorn, but it is designed to handle slow
clients. It offers many concurrency options, and some of them offer
rack.input streaming like Unicorn does. I recommend
ThreadSpawn/ThreadPool for the greatest compatibility if you want input
streaming[4].
> After some initial testing, it appears to me that the former is the case.
> Can anyone give me advice on how to test this? Perhaps it depends on the web
> server used? Perhaps on the framework?
The framework also matters. You'll want to audit all your layers and
make sure they don't call methods like "rewind" or "size" on the
env["rack.input"] object.
I once wrote an app (which I haven't touched in a long time,
but probably still works) to do upload progress with Rack + Rainbows!
based on the streaming rack.input support I have:
[1] http://unicorn.bogomips.org/
[2] http://unicorn.bogomips.org/Unicorn/Configurator.html#method-i-rewindable_input
[3] http://rainbows.rubyforge.org/
[4] http://rainbows.rubyforge.org/Summary.html
--
Eric Wong