Class: Goliath::Rack::SimpleAroundwareFactory
- Inherits:
-
Object
- Object
- Goliath::Rack::SimpleAroundwareFactory
- Includes:
- Validator
- Defined in:
- lib/goliath/rack/simple_aroundware_factory.rb
Overview
Include this to enable middleware that can perform pre- and post-processing.
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 a “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.
Direct Known Subclasses
Instance Method Summary collapse
-
#call(env) ⇒ Array
Coordinates aroundware to process a request.
- #final_response?(resp) ⇒ Boolean
-
#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.
-
#initialize(app, aroundware_klass, *args) ⇒ Goliath::Rack::AroundwareFactory
constructor
Called by the framework to create the middleware.
-
#new_aroundware(env) ⇒ Goliath::Rack::SimpleAroundware
Generate a aroundware to process the request, using request env & any args passed to this AroundwareFactory at creation.
Methods included from Validator
Constructor Details
#initialize(app, aroundware_klass, *args) ⇒ Goliath::Rack::AroundwareFactory
Called by the framework to create the middleware.
Any extra args passed to the use statement are sent to each aroundware_klass as it is created.
54 55 56 57 58 |
# File 'lib/goliath/rack/simple_aroundware_factory.rb', line 54 def initialize app, aroundware_klass, *args @app = app @aroundware_klass = aroundware_klass @aroundware_args = args end |
Instance Method Details
#call(env) ⇒ Array
Coordinates aroundware to process a request.
We hook the aroundware in the middle of the async_callback chain:
-
send the downstream response to the aroundware, whether received directly from @app.call or via async callback
-
have the upstream callback chain be invoked when the aroundware completes
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/goliath/rack/simple_aroundware_factory.rb', line 69 def call(env) aroundware = new_aroundware(env) aroundware_resp = aroundware.pre_process return aroundware_resp if final_response?(aroundware_resp) hook_into_callback_chain(env, aroundware) downstream_resp = @app.call(env) # if downstream resp is final, pass it to the aroundware; it will invoke # the callback chain at its leisure. Our response is *always* async. if final_response?(downstream_resp) aroundware.accept_response(:downstream_resp, true, downstream_resp) end return Goliath::Connection::AsyncResponse end |
#final_response?(resp) ⇒ Boolean
106 107 108 |
# File 'lib/goliath/rack/simple_aroundware_factory.rb', line 106 def final_response?(resp) resp != Goliath::Connection::AsyncResponse end |
#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
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/goliath/rack/simple_aroundware_factory.rb', line 92 def hook_into_callback_chain(env, aroundware) async_callback = env['async.callback'] # The response from the downstream app is accepted by the aroundware... # ... and we immediately call post_process and hand it upstream downstream_callback = Proc.new do |resp| safely(env){ aroundware.accept_response(:downstream_resp, true, resp) } new_resp = safely(env){ aroundware.post_process } async_callback.call(new_resp) end env['async.callback'] = downstream_callback end |
#new_aroundware(env) ⇒ Goliath::Rack::SimpleAroundware
Generate a aroundware to process the request, using request env & any args passed to this AroundwareFactory at creation
115 116 117 |
# File 'lib/goliath/rack/simple_aroundware_factory.rb', line 115 def new_aroundware(env) @aroundware_klass.new(env, *@aroundware_args) end |