Class: Roda::RodaPlugins::Streaming::Stream

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/roda/plugins/streaming.rb

Overview

Class of the response body in case you use #stream.

Three things really matter: The front and back block (back being the block generating content, front the one sending it to the client) and the scheduler, integrating with whatever concurrency feature the Rack handler is using.

Scheduler has to respond to defer and schedule.

Defined Under Namespace

Classes: Scheduler

Instance Method Summary collapse

Constructor Details

#initialize(opts = RodaPlugins::OPTS, &back) ⇒ Stream

Handle streaming options, see Streaming for details.



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/roda/plugins/streaming.rb', line 113

def initialize(opts=RodaPlugins::OPTS, &back)
  @scheduler = opts[:scheduler] || Scheduler.new(self)
  @back = back.to_proc
  @keep_open = opts[:keep_open]
  @callbacks = []
  @closed = false

  if opts[:callback]
    @callbacks << opts[:callback]
  end
end

Instance Method Details

#<<(data) ⇒ Object

Alias for write.



132
133
134
# File 'lib/roda/plugins/streaming.rb', line 132

def <<(data)
  write(data)
end

#callback(&block) ⇒ Object Also known as: errback

Add the given block as a callback to call when the block closes.



137
138
139
140
141
# File 'lib/roda/plugins/streaming.rb', line 137

def callback(&block)
  RodaPlugins.warn 'Stream#callback in the streaming plugin is deprecated and will be removed in Roda 3.  Specify callback at initialization using the stream method :callback option.'
  return yield if closed?
  @callbacks << block
end

#closeObject

If not already closed, close the connection, and call any callbacks.



148
149
150
151
152
# File 'lib/roda/plugins/streaming.rb', line 148

def close
  return if closed?
  @closed = true
  @scheduler.schedule{@callbacks.each(&:call)}
end

#closed?Boolean

Whether the connection has already been closed.

Returns:

  • (Boolean)


155
156
157
# File 'lib/roda/plugins/streaming.rb', line 155

def closed?
  @closed
end

#each(&front) ⇒ Object

Yield values to the block as they are passed in via #<<.



160
161
162
163
164
165
166
167
168
169
170
# File 'lib/roda/plugins/streaming.rb', line 160

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

#write(data) ⇒ Object

Add output to the streaming response body.



126
127
128
129
# File 'lib/roda/plugins/streaming.rb', line 126

def write(data)
  @scheduler.schedule{@front.call(data.to_s)}
  self
end