class Tom::Dispatcher
Public Class Methods
Dispatches this request to all adapters that registered for the route and then calls the merger for this route to compose a response
@param env [Array] A rack env object
@return [Array] Whatever {Tom::Dispatcher.merge} had to say
# File lib/dispatcher.rb, line 13 def self.dispatch(env) # 1. hit APIs. All at the same time. Oh, mygodd! Tom::Log.logger.info "#{env['REQUEST_METHOD'].upcase} #{env['REQUEST_URI']}" responses = parallel_adapter_dispatch(env) # 2. merge merged = merge(env, responses) # 3. ??? Tom::Log.logger.info "-------------------------------------------------------" # 4. profit merged end
Takes a request (rack env) and a couple of responses generated by api adapters and composes a response for the client.
The merger used depends on the route.
@param env [Array] A rack env object
@return [Array] The merged result of all requests
made as an array of status code, headers and body, e.g. [200, {}, "Hi!"]
# File lib/dispatcher.rb, line 40 def self.merge(env, responses) route, method = route_and_method(env) if merger = Tom::Routes.merger_for_route(route, method) Tom::Log.logger.info "Merging with:" Tom::Log.logger.info " -> #{merger}" merged = merger.new.merge(env, responses) else merged = [404, {}, ""] end merged[1]["Adapters-Used"] = responses.keys.join(",") merged end
Extract the route/request uri and the method from a rack env
@param env [Hash] A rack env
@return [Array] Contains request_path, request_method as symbols
# File lib/dispatcher.rb, line 61 def self.route_and_method(env) [env["REQUEST_PATH"], env["REQUEST_METHOD"].downcase.to_sym] end
Private Class Methods
Uses a EM::Synchrony::FiberIterator to call all adapters that registered for this route at the same time.
@param env [Hash] A rack env object
@return [Hash] Keys are the adapter classes, values are arrays of responses
they generated (the [status_code, headers, body] triplets)
# File lib/dispatcher.rb, line 75 def self.parallel_adapter_dispatch(env) responses = {} route, method = route_and_method(env) adapters = Tom::Routes.adapters_for_route(route, method) return responses if adapters.empty? Tom::Log.logger.info "Dispatching to:" EM::Synchrony::FiberIterator.new(adapters, adapters.count).map do |clazz| Tom::Log.logger.info " -> #{clazz}" (responses[clazz] ||= []) << clazz.new.handle(env) end responses end