class Roda::RodaPlugins::Streaming::Stream

Scheduler has to respond to defer and schedule.
handler is using.
the scheduler, integrating with whatever concurrency feature the Rack
block generating content, front the one sending it to the client) and
Three things really matter: The front and back block (back being the
Class of the response body in case you use #stream.

def <<(data)

Add output to the streaming response body.
def <<(data)
  @scheduler.schedule{@front.call(data.to_s)}
  self
end

def callback(&block)

Add the given block as a callback to call when the block closes.
def callback(&block)
  return yield if closed?
  @callbacks << block
end

def close

any callbacks.
If not already closed, close the connection, and call
def close
  return if closed?
  @closed = true
  @scheduler.schedule{@callbacks.each(&:call)}
end

def closed?

Whether the connection has already been closed.
def closed?
  @closed
end

def each(&front)

Yield values to the block as they are passed in via #<<.
def each(&front)
  @front = front
  @scheduler.defer do
    begin
      @back.call(self)
    rescue Exception => e
      @scheduler.schedule{raise e}
    end
    close unless @keep_open
  end
end

def initialize(opts=OPTS, &back)

Handle streaming options, see Streaming for details.
def initialize(opts=OPTS, &back)
  @scheduler = opts[:scheduler] || Scheduler.new(self)
  @back = back.to_proc
  @keep_open = opts[:keep_open]
  @callbacks = []
  @closed = false
  if opts[:callback]
    callback(&opts[:callback])
  end
end