Module: Sinatra::Async::Helpers
- Defined in:
- lib/sinatra/async.rb
Instance Attribute Summary collapse
-
#aparams ⇒ Object
readonly
aparams are used when inside of something that has been scheduled asynchronously in an asynchronous route.
Instance Method Summary collapse
-
#ahalt(*args) ⇒ Object
Asynchronous halt must be used when the halt is occuring outside of the original call stack.
- #async_catch_execute(&b) ⇒ Object
- #async_handle_exception ⇒ Object
-
#async_response ⇒ Object
Defaults to throw async as that is most commonly used by servers.
- #async_runner(meth, *bargs) ⇒ Object
-
#async_schedule(&b) ⇒ Object
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.
-
#body(value = nil) ⇒ Object
Send the given body or block as the final response to the asynchronous request.
-
#native_async_schedule(&b) ⇒ Object
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.
-
#on_close(&blk) ⇒ Object
The given block will be executed if the user closes the connection prematurely (before we’ve sent a response).
Instance Attribute Details
#aparams ⇒ Object (readonly)
aparams are used when inside of something that has been scheduled asynchronously in an asynchronous route. Essentially it is the last parameters to be set by the router (for example, containing the route captures).
85 86 87 |
# File 'lib/sinatra/async.rb', line 85 def aparams @aparams end |
Instance Method Details
#ahalt(*args) ⇒ Object
Asynchronous halt must be used when the halt is occuring outside of the original call stack.
188 189 190 191 |
# File 'lib/sinatra/async.rb', line 188 def ahalt(*args) invoke { halt(*args) } invoke { error_block! response.status } unless @env['sinatra.error'] end |
#async_catch_execute(&b) ⇒ Object
160 161 162 163 164 165 166 167 168 169 |
# File 'lib/sinatra/async.rb', line 160 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 |
#async_handle_exception ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/sinatra/async.rb', line 171 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 |
#async_response ⇒ Object
Defaults to throw async as that is most commonly used by servers.
143 144 145 |
# File 'lib/sinatra/async.rb', line 143 def async_response throw :async end |
#async_runner(meth, *bargs) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/sinatra/async.rb', line 147 def async_runner(meth, *) @aparams = @params.dup async_schedule do begin original, @params = @params, @aparams method(meth).arity == 0 ? send(meth) : send(meth, *) ensure @params = original end nil end end |
#async_schedule(&b) ⇒ Object
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.
126 127 128 129 130 131 132 133 |
# File 'lib/sinatra/async.rb', line 126 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 |
#body(value = nil) ⇒ Object
Send the given body or block as the final response to the asynchronous request.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/sinatra/async.rb', line 89 def body(value = nil) if @async_running 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 === response.body and response.body[0].respond_to? :content_type content_type response.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 ] response.body else super end end |
#native_async_schedule(&b) ⇒ Object
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.
138 139 140 |
# File 'lib/sinatra/async.rb', line 138 def native_async_schedule(&b) EM.next_tick(&b) end |
#on_close(&blk) ⇒ Object
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).
197 198 199 |
# File 'lib/sinatra/async.rb', line 197 def on_close(&blk) env['async.close'].callback(&blk) end |