Static file serving with Rainbows!

While Ruby application servers aren't traditionally used to serve static files, it'll be fun for us to see how far we can go with Rainbows!

We aren't delusional enough (yet :) to compete with C-based servers like nginx or lighttpd in terms of raw performance, but wouldn't it be nice to simplify your deployments and only deploy one server?

sendfile RubyGem

To enable the “sendfile” gem, just make sure you have 1.1.0 or later and “require” it in your Rainbows!/Unicorn config file (not your Rack config.ru):

require 'sendfile' # that's it! nothing else to do

# the rest of you Rainbows! config goes below:
worker_processes 4
stderr_path "/var/log/app/rainbows.err.log"
Rainbows! do
  use :RevFiberSpawn
  worker_connections 100
end

The sendfile gem is works for all of our concurrency models except NeverBlock and EventMachine (see below).

The sendfile gem is less buggy than current (Ruby 1.9.2) IO.copy_stream and supports FreeBSD and Solaris in addition to Linux. This RubyGem also works under Ruby 1.8 (even with threads) and should work with rubinius.git, too.

Rainbows! supports the sendfile gem since v0.95.0

IO.copy_stream (Ruby 1.9 only)

Users of pure-Ruby Thread-based models ThreadPool, ThreadSpawn, and their Writer* variants use the core IO.copy_stream method under Ruby 1.9. IO.copy_stream uses sendfile() under Linux, and a pread()/write() loop (implemented in C) on other systems.

IO.copy_stream under Linux with Ruby 1.9.2 (and before) is also subject to hanging indefinitely when a client disconnected prematurely. This issue is fixed in Ruby trunk (r28557, July 2010).

Rainbows! supports IO.copy_stream since v0.93.0

EventMachine FileStreamer

EventMachine and NeverBlock users automatically take advantage of the mmap()-based FileStreamer class distributed with EventMachine. Unfortunately, as of EventMachine 0.12.10, FileStreamer cannot easily support HTTP Range responses.

Rainbows! supports EventMachine FileStreamer since v0.4.0

Performance

With large files and high-throughput clients, there should be little performance difference compared to optimal C implementation such as nginx and lighttpd. Ruby runtime overhead matters more when serving slower clients and smaller files.

The Future…

We'll also support an open file cache (similar to nginx) which allows us to reuse open file descriptors.

Under Linux, we'll support the splice(2) system call for zero-copy proxying io_splice, too.

Originally generated with the Darkfish Rdoc Generator 2, modified by wrongdoc.

We love to hear from you!
Email patches (with git send-email), pull requests, questions, bug reports, suggestions, etc. to us publically at rainbows-talk@rubyforge.org.
No subscription to the mailing list is necessary, just let us know to Cc: you if you're unsubscribed.
To subscribe, email rainbows-talk-request@rubyforge.org with "subscribe" in the Subject and respond to the automated confirmation message.
Do not waste bandwidth with HTML, HTML mail will not be read.
Quote only parts you're responding to and do not top post.
For sensitive topics, email us privately at rainbows@bogomips.org.