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.
-
#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(args = {}) ⇒ Dispatcher
constructor
RJR::Dispatcher intializer.
-
#requests ⇒ Object
Requests which have been dispatched.
Constructor Details
#initialize(args = {}) ⇒ Dispatcher
RJR::Dispatcher intializer
194 195 196 197 198 199 |
# File 'lib/rjr/dispatcher.rb', line 194 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
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 |
#keep_requests ⇒ Object
Flag toggling whether or not to keep requests (& responses) around.
188 189 190 |
# File 'lib/rjr/dispatcher.rb', line 188 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.
216 217 218 219 220 221 222 223 |
# File 'lib/rjr/dispatcher.rb', line 216 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
202 203 204 205 206 |
# File 'lib/rjr/dispatcher.rb', line 202 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
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 308 309 310 311 312 313 314 315 316 |
# File 'lib/rjr/dispatcher.rb', line 275 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 } if @keep_requests 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
262 263 264 265 266 267 268 269 |
# File 'lib/rjr/dispatcher.rb', line 262 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
232 233 234 235 236 237 238 239 240 |
# File 'lib/rjr/dispatcher.rb', line 232 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
321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/rjr/dispatcher.rb', line 321 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
246 247 248 249 250 251 252 |
# File 'lib/rjr/dispatcher.rb', line 246 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
191 |
# File 'lib/rjr/dispatcher.rb', line 191 def requests ; @requests_lock.synchronize { Array.new(@requests) } ; end |