Asynchronous halt must be used when the halt is occuring outside of the original call stack.
# File lib/sinatra/async.rb, line 181 def ahalt(*args) invoke { halt(*args) } invoke { error_block! response.status } body response.body end
# File lib/sinatra/async.rb, line 153 def async_catch_execute(&b) @async_running = true async_handle_exception do if h = catch(:halt, &b) invoke { halt h } invoke { error_block! response.status } body(response.body) end end end
# File lib/sinatra/async.rb, line 164 def async_handle_exception yield rescue ::Exception => boom if settings.show_exceptions? printer = Sinatra::ShowExceptions.new(proc{ raise boom }) s, h, b = printer.call(request.env) response.status = s response.headers.replace(h) response.body = b body(response.body) else body(handle_exception!(boom)) end end
Defaults to throw async as that is most commonly used by servers.
# File lib/sinatra/async.rb, line 136 def async_response throw :async end
# File lib/sinatra/async.rb, line 140 def async_runner(meth, *bargs) @aparams = @params.dup async_schedule do begin original, @params = @params, @aparams method(meth).arity == 0 ? send(meth) : send(meth, *bargs) ensure @params = original end nil end end
async_schedule is used to schedule work in a future context, the block is wrapped up so that exceptions and halts (redirect, etc) are handled correctly.
# File lib/sinatra/async.rb, line 119 def async_schedule(&b) if settings.environment == :test settings.set :async_schedules, [] unless settings.respond_to? :async_schedules settings.async_schedules << lambda { async_catch_execute(&b) } else native_async_schedule { async_catch_execute(&b) } end end
Send the given body or block as the final response to the asynchronous request.
# File lib/sinatra/async.rb, line 82 def body(value = nil) if @async_running && (value || block_given?) if block_given? super { async_handle_exception { yield } } else super end if response.body.respond_to?(:call) response.body = Array(async_handle_exception {response.body.call}) end # Taken from Base#call unless @response['Content-Type'] if Array === body and body[0].respond_to? :content_type content_type body[0].content_type else content_type :html end end result = response.finish # We don't get the HEAD middleware, so just do something convenient # here. result[-1] = [] if request.head? request.env['async.callback'][ result ] body else super end end
By default native_async_schedule calls EventMachine#next_tick, if you’re using threads or some other scheduling mechanism, it must take the block passed here and schedule it for running in the future.
# File lib/sinatra/async.rb, line 131 def native_async_schedule(&b) EM.next_tick(&b) end
The given block will be executed if the user closes the connection prematurely (before we’ve sent a response). This is good for deregistering callbacks that would otherwise send the body (for example channel subscriptions).
# File lib/sinatra/async.rb, line 191 def on_close(&blk) env['async.close'].callback(&blk) end
Generated with the Darkfish Rdoc Generator 2.