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).
78 79 80 |
# File 'lib/sinatra/async.rb', line 78 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.
181 182 183 184 185 |
# File 'lib/sinatra/async.rb', line 181 def ahalt(*args) invoke { halt(*args) } invoke { error_block! response.status } body response.body end |
#async_catch_execute(&b) ⇒ Object
153 154 155 156 157 158 159 160 161 162 |
# 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 |
#async_handle_exception ⇒ Object
164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# 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 |
#async_response ⇒ Object
Defaults to throw async as that is most commonly used by servers.
136 137 138 |
# File 'lib/sinatra/async.rb', line 136 def async_response throw :async end |
#async_runner(meth, *bargs) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/sinatra/async.rb', line 140 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.
119 120 121 122 123 124 125 126 |
# 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 |
#body(value = nil) ⇒ Object
Send the given body or block as the final response to the asynchronous request.
82 83 84 85 86 87 88 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 |
# 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 |
#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.
131 132 133 |
# File 'lib/sinatra/async.rb', line 131 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).
191 192 193 |
# File 'lib/sinatra/async.rb', line 191 def on_close(&blk) env['async.close'].callback(&blk) end |