Class: RJR::Dispatcher
Overview
Primary RJR JSON-RPC method dispatcher.
Instance Attribute Summary collapse
-
#environments ⇒ Object
readonly
Registered json-rpc request signatures and environments which to execute handlers in.
-
#handlers ⇒ Object
readonly
Registered json-rpc request signatures and corresponding handlers.
-
#keep_requests ⇒ Object
Flag toggling whether or not to keep requests (& responses) around.
Instance Method Summary collapse
-
#add_module(name) ⇒ Object
(also: #add_modules)
Loads module from fs and adds handlers defined there.
-
#clear! ⇒ Object
Return dispatcher to its initial state.
-
#dispatch(args = {}) ⇒ Object
Dispatch received request.
-
#env(signature, environment) ⇒ Object
Register environment to run json-rpc handler w/ dispatcher.
-
#env_for(rjr_method) ⇒ Object
Return the environment registered for the specified method.
-
#handle(signature, callback = nil, &bl) ⇒ Object
Register json-rpc handler with dispatcher.
-
#handle_response(result) ⇒ Object
Handle responses received from rjr requests.
-
#handler_for(rjr_method) ⇒ Callable?
Return handler for specified method.
-
#handles?(rjr_method) ⇒ true, false
Return boolean indicating if dispatcher can handle method.
-
#initialize(args = {}) ⇒ Dispatcher
constructor
RJR::Dispatcher intializer.
-
#requests ⇒ Object
Requests which have been dispatched.
-
#store_request(request) ⇒ Object
Store request if configured to do so.
Constructor Details
#initialize(args = {}) ⇒ Dispatcher
RJR::Dispatcher intializer
37 38 39 40 41 42 |
# File 'lib/rjr/dispatcher.rb', line 37 def initialize(args = {}) @keep_requests = args[:keep_requests] || false clear! @requests_lock = Mutex.new end |
Instance Attribute Details
#environments ⇒ Object (readonly)
Registered json-rpc request signatures and environments which to execute handlers in
21 22 23 |
# File 'lib/rjr/dispatcher.rb', line 21 def environments @environments end |
#handlers ⇒ Object (readonly)
Registered json-rpc request signatures and corresponding handlers
18 19 20 |
# File 'lib/rjr/dispatcher.rb', line 18 def handlers @handlers end |
#keep_requests ⇒ Object
Flag toggling whether or not to keep requests (& responses) around.
24 25 26 |
# File 'lib/rjr/dispatcher.rb', line 24 def keep_requests @keep_requests end |
Instance Method Details
#add_module(name) ⇒ Object Also known as: add_modules
Loads module from fs and adds handlers defined there
Assumes module includes a ‘dispatch_<module_name>’ method which accepts a dispatcher and defines handlers on it.
59 60 61 62 63 64 65 66 |
# File 'lib/rjr/dispatcher.rb', line 59 def add_module(name) require name m = name.downcase.gsub(File::SEPARATOR, '_') method("dispatch_#{m}".intern).call(self) self end |
#clear! ⇒ Object
Return dispatcher to its initial state
45 46 47 48 49 |
# File 'lib/rjr/dispatcher.rb', line 45 def clear! @handlers = {} @environments = {} @requests = [] end |
#dispatch(args = {}) ⇒ Object
Dispatch received request. (used internally by nodes).
Arguments should include :rjr_method and other parameters required to construct a valid Request instance
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rjr/dispatcher.rb', line 141 def dispatch(args = {}) rjr_method = args[:rjr_method] # *note* not using concurrent access protection, # assumes all handlers/enviroments are registered # before first dispatch occurs handler = handler_for(rjr_method) environment = env_for(rjr_method) return Result.method_not_found(rjr_method) if handler.nil? request = Request.new args.merge(:rjr_handler => handler) # set request environment request.extend(environment) unless environment.nil? begin retval = request.handle request.result = Result.new(:result => retval) rescue Exception => e warning = "Exception Raised in #{rjr_method} handler #{e}" RJR::Logger.warn [warning] + e.backtrace request.result = Result.new(:error_code => -32000, :error_msg => e.to_s, :error_class => e.class) end store_request request return request.result end |
#env(signature, environment) ⇒ Object
Register environment to run json-rpc handler w/ dispatcher.
Currently environments may be set to modules which requests will extend before executing handler
117 118 119 120 121 122 123 124 |
# File 'lib/rjr/dispatcher.rb', line 117 def env(signature, environment) if signature.is_a?(Array) signature.each { |s| env(s, environment) } return self end @environments[signature] = environment self end |
#env_for(rjr_method) ⇒ Object
Return the environment registered for the specified method
127 128 129 130 131 132 133 134 135 |
# File 'lib/rjr/dispatcher.rb', line 127 def env_for(rjr_method) # look for exact match first env = @environments.find { |k,v| k == rjr_method } # if not found try to match regex's env ||= @environments.find { |k,v| k.is_a?(Regexp) && (k =~ rjr_method) } env.nil? ? nil : env.last end |
#handle(signature, callback = nil, &bl) ⇒ Object
Register json-rpc handler with dispatcher
75 76 77 78 79 80 81 82 83 |
# File 'lib/rjr/dispatcher.rb', line 75 def handle(signature, callback = nil, &bl) if signature.is_a?(Array) signature.each { |s| handle(s, callback, &bl) } return self end @handlers[signature] = callback unless callback.nil? @handlers[signature] = bl unless bl.nil? self end |
#handle_response(result) ⇒ Object
Handle responses received from rjr requests. (used internally by nodes)
Returns return-value of method handler or raises error
177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/rjr/dispatcher.rb', line 177 def handle_response(result) unless result.success #if result.error_class # TODO needs to be constantized first (see TODO in lib/rjr/message) # raise result.error_class.new(result.error_msg) unless result.success #else raise Exception, result.error_msg #end end return result.result end |
#handler_for(rjr_method) ⇒ Callable?
Return handler for specified method.
Currently we match method name string or regex against signature
91 92 93 94 95 96 97 98 99 |
# File 'lib/rjr/dispatcher.rb', line 91 def handler_for(rjr_method) # look for exact match first handler = @handlers.find { |k,v| k == rjr_method } # if not found try to match regex's handler ||= @handlers.find { |k,v| k.is_a?(Regexp) && (k =~ rjr_method) } handler.nil? ? nil : handler.last end |
#handles?(rjr_method) ⇒ true, false
Return boolean indicating if dispatcher can handle method
105 106 107 |
# File 'lib/rjr/dispatcher.rb', line 105 def handles?(rjr_method) !handler_for(rjr_method).nil? end |
#requests ⇒ Object
Requests which have been dispatched
27 28 29 |
# File 'lib/rjr/dispatcher.rb', line 27 def requests @requests_lock.synchronize { Array.new(@requests) } end |
#store_request(request) ⇒ Object
Store request if configured to do so
32 33 34 |
# File 'lib/rjr/dispatcher.rb', line 32 def store_request(request) @requests_lock.synchronize { @requests << request } if @keep_requests end |