Module: Sinatra::Async::InstanceMethods
- Defined in:
- lib/sinatra/async.rb
Instance Method Summary collapse
-
#async(method_name = nil, &block) ⇒ Object
Repond to this request asynchronously.
-
#async_call! ⇒ Object
Resumes #call! and sends an asynchronous response.
-
#async_respond(response) ⇒ Object
Respond to an existing asynchronous request.
Instance Method Details
#async(method_name = nil, &block) ⇒ Object
Repond to this request asynchronously.
Can be passed a block or method name which will be queued for execution, or just aborts the current flow and presumes you’ll respond later.
The return value of the supplied block or method will be used as a response, as per a normal Sinatra route handler, unless:
* If it is an EM::Deferrable, we will respond as a succeed
callback.
* If it is nil, is an EM::Timer or EM::PeriodicTimer we
presume you'll respond later using #async_respond.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/sinatra/async.rb', line 21 def async method_name=nil, &block raise RuntimeError, 'Not running in async capable server -- try Thin' unless env.has_key?('async.callback') block ||= method method_name if method_name if block EM.next_tick do catch :async do returned = invoke { route_eval &block } if returned.is_a? EventMachine::Deferrable returned.callback do |*args| invoke { throw :halt, args.first } unless args.empty? async_call! end elsif returned.is_a?(EventMachine::Timer) || returned.is_a?(EventMachine::PeriodicTimer) returned = nil end async_call! unless returned.nil? end end end throw :async end |
#async_call! ⇒ Object
Resumes #call! and sends an asynchronous response
To DRY this up we’d need to break up Sinatra::Base#call!
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/sinatra/async.rb', line 57 def async_call! invoke { error_block! response.status } unless @response['Content-Type'] if body.respond_to?(:to_ary) and body.first.respond_to? :content_type content_type body.first.content_type else content_type :html end end status, header, body = @response.finish # Never produce a body on HEAD requests. Do retain the Content-Length # unless it's "0", in which case we assume it was calculated erroneously # for a manual HEAD response and remove it entirely. if @env['REQUEST_METHOD'] == 'HEAD' body = [] header.delete('Content-Length') if header['Content-Length'] == '0' end env['async.callback'].call [status, header, body] end |
#async_respond(response) ⇒ Object
Respond to an existing asynchronous request.
49 50 51 52 |
# File 'lib/sinatra/async.rb', line 49 def async_respond response invoke { throw :halt, response } async_call! end |