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.
Instance Method Summary collapse
-
#add_module(name) ⇒ Object
(also: #add_modules)
Loads module from fs and adds handlers defined there.
-
#dispatch(args = {}) ⇒ Object
Dispatch received request.
-
#env(signature, environment) ⇒ Object
Register environment to run json-rpc handler w/ dispatcher.
-
#handle(signature, callback = nil, &bl) ⇒ Object
Register json-rpc handler with dispatcher.
-
#handle_response(result) ⇒ Object
Handle responses received from rjr requests.
-
#handles?(rjr_method) ⇒ true, false
Return boolean indicating if dispatcher can handle method.
-
#initialize ⇒ Dispatcher
constructor
RJR::Dispatcher intializer.
-
#requests ⇒ Object
Requests which have been dispatched.
Constructor Details
#initialize ⇒ Dispatcher
RJR::Dispatcher intializer
191 192 193 194 195 196 197 |
# File 'lib/rjr/dispatcher.rb', line 191 def initialize @handlers = Hash.new() @environments = Hash.new() @requests_lock = Mutex.new @requests = [] end |
Instance Attribute Details
#environments ⇒ Object (readonly)
Registered json-rpc request signatures and environments which to execute handlers in
185 186 187 |
# File 'lib/rjr/dispatcher.rb', line 185 def environments @environments end |
#handlers ⇒ Object (readonly)
Registered json-rpc request signatures and corresponding handlers
182 183 184 |
# File 'lib/rjr/dispatcher.rb', line 182 def handlers @handlers 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.
207 208 209 210 211 212 213 214 |
# File 'lib/rjr/dispatcher.rb', line 207 def add_module(name) require name m = name.downcase.gsub(File::SEPARATOR, '_') method("dispatch_#{m}".intern).call(self) self 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
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/rjr/dispatcher.rb', line 266 def dispatch(args = {}) # currently we match method name string or regex against signature # TODO not using concurrent access protection, assumes all handlers are registered # before first dispatch occurs handler = @handlers.find { |k,v| k.is_a?(String) ? k == args[:rjr_method] : k =~ args[:rjr_method] } # TODO currently just using last environment that matches, # allow multiple environments to be used? environment = @environments.keys.select { |k| k.is_a?(String) ? k == args[:rjr_method] : k =~ args[:rjr_method] }.last return Result.method_not_found(args[:rjr_method]) if handler.nil? # TODO compare arity of handler to number of method_args passed in request = Request.new args.merge(:rjr_handler => handler.last) # set request environment request.extend(@environments[environment]) unless environment.nil? begin retval = request.handle request.result = Result.new(:result => retval) rescue Exception => e RJR::Logger.warn ["Exception Raised in #{args[:rjr_method]} handler #{e}"] + e.backtrace request.result = Result.new(:error_code => -32000, :error_msg => e.to_s, :error_class => e.class) end @requests_lock.synchronize { @requests << 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
253 254 255 256 257 258 259 260 |
# File 'lib/rjr/dispatcher.rb', line 253 def env(signature, environment) if signature.is_a?(Array) signature.each { |s| env(s, environment) } return self end @environments[signature] = environment self end |
#handle(signature, callback = nil, &bl) ⇒ Object
Register json-rpc handler with dispatcher
223 224 225 226 227 228 229 230 231 |
# File 'lib/rjr/dispatcher.rb', line 223 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
312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/rjr/dispatcher.rb', line 312 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 |
#handles?(rjr_method) ⇒ true, false
Return boolean indicating if dispatcher can handle method
237 238 239 240 241 242 243 |
# File 'lib/rjr/dispatcher.rb', line 237 def handles?(rjr_method) !@handlers.find { |k,v| k.is_a?(String) ? k == rjr_method : k =~ rjr_method }.nil? end |
#requests ⇒ Object
Requests which have been dispatched
188 |
# File 'lib/rjr/dispatcher.rb', line 188 def requests ; @requests_lock.synchronize { Array.new(@requests) } ; end |