Module | Sinatra::Streaming |
In: |
lib/sinatra/streaming.rb
|
Sinatra 1.3 introduced the stream helper. This addon improves the streaming API by making the stream object imitate 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