2012-07-09 20:57:47 +00:00
|
|
|
# Super-simple Rack streaming with Thin and other EventMachine-based servers
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
This is the absolute simplest way to turn any Rack app into a streaming- and deferrable-capable service using Thin.
|
|
|
|
It handles the necessary async calls to make Thin start streaming, then delivers your
|
|
|
|
response body on each next tick until sent. If you're sending something big, make sure it responds to `each`
|
|
|
|
in chunks:
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
``` ruby
|
|
|
|
class FileStreamer
|
|
|
|
def initialize(file)
|
|
|
|
@file = file
|
|
|
|
end
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
def each
|
|
|
|
while !@file.eof?
|
|
|
|
yield @file.read(8192)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
# then respond with a FileStreamer
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
def call(env)
|
|
|
|
# ... do stuff ...
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
[ 200, {}, FileStreamer.new(File.open('big-file.mpg')) ]
|
|
|
|
end
|
|
|
|
```
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
Nothing to configure, just drop it in to your Rack middleware stack and
|
|
|
|
use Thin as your server:
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
``` ruby
|
|
|
|
# for Rails:
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
config.middleware.insert_before(::Rack::Lock, ::Rack::EMStream)
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
# for Rack::Builder and derivatives:
|
2012-05-04 20:45:47 +00:00
|
|
|
|
2012-07-09 20:57:47 +00:00
|
|
|
use Rack::EMStream
|
|
|
|
```
|
2012-05-04 20:45:47 +00:00
|
|
|
|