Class: Goliath::Rack::BarrierAroundwareFactory
- Inherits:
-
SimpleAroundwareFactory
- Object
- SimpleAroundwareFactory
- Goliath::Rack::BarrierAroundwareFactory
- Includes:
- Validator
- Defined in:
- lib/goliath/rack/barrier_aroundware_factory.rb
Overview
Include this to enable middleware that can perform pre- and post-processing, orchestrating multiple concurrent requests.
For internal reasons, you can’t do the following as you would in Rack:
def call(env)
# ... do pre-processing
status, headers, body = @app.call(env)
new_body = make_totally_awesome(body) ## !! BROKEN !!
[status, headers, new_body]
end
This class creates an “aroundware” helper to do that kind of processing. Goliath proceeds asynchronously, but will still “unwind” the request by walking up the callback chain. Delegating out to the aroundware also lets you carry state around – the ban on instance variables no longer applies, as each aroundware is unique per request.
The strategy here is similar to that in EM::Multi. Figuring out what goes on there will help you understand this.
Instance Method Summary collapse
-
#hook_into_callback_chain(env, aroundware) ⇒ Object
Put aroundware in the middle of the async_callback chain: * save the old callback chain; * have the downstream callback send results to the aroundware (possibly completing it) * set the old callback chain to fire when the aroundware completes.
Methods included from Validator
Methods inherited from SimpleAroundwareFactory
#call, #final_response?, #initialize, #new_aroundware
Constructor Details
This class inherits a constructor from Goliath::Rack::SimpleAroundwareFactory
Instance Method Details
#hook_into_callback_chain(env, aroundware) ⇒ Object
Put aroundware in the middle of the async_callback chain:
-
save the old callback chain;
-
have the downstream callback send results to the aroundware (possibly completing it)
-
set the old callback chain to fire when the aroundware completes
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/goliath/rack/barrier_aroundware_factory.rb', line 38 def hook_into_callback_chain(env, aroundware) async_callback = env['async.callback'] # The response from the downstream app is accepted by the aroundware... downstream_callback = Proc.new do |resp| safely(env){ aroundware.accept_response(:downstream_resp, true, resp) } end # .. but the upstream chain is only invoked when the aroundware completes invoke_upstream_chain = Proc.new do new_resp = safely(env){ aroundware.post_process } async_callback.call(new_resp) end env['async.callback'] = downstream_callback aroundware.add_to_pending(:downstream_resp) aroundware.callback(&invoke_upstream_chain) aroundware.errback(&invoke_upstream_chain) end |