Sinatra 1.3 introduced the stream helper. This addon improves the streaming API by making the stream object immitate an IO object, turning it into a real Deferrable and making the body play nicer with middleware unaware of streaming.
This is useful when passing the stream object to a library expecting an IO or StringIO object.
get '/' do
stream do |out|
out.puts "Hello World!", "How are you?"
out.write "Written #{out.pos} bytes so far!\n"
out.putc(65) unless out.closed?
out.flush
end
end
Blocks passed to map! or map will actually be applied when streaming takes place (as you might have suspected, map! applies modifications to the current body, while map creates a new one):
class StupidMiddleware
def initialize(app) @app = app end
def call(env)
status, headers, body = @app.call(env)
body.map! { |e| e.upcase }
[status, headers, body]
end
end
use StupidMiddleware
get '/' do
stream do |out|
out.puts "still"
sleep 1
out.puts "streaming"
end
end
Even works if each is used to generate an Enumerator:
def call(env)
status, headers, body = @app.call(env)
body = body.each.map { |s| s.upcase }
[status, headers, body]
end
Note that both examples violate the Rack specification.
In a classic application:
require "sinatra" require "sinatra/streaming"
In a modular application:
require "sinatra/base" require "sinatra/streaming" class MyApp < Sinatra::Base helpers Sinatra::Streaming end
Generated with the Darkfish Rdoc Generator 2.