class RJR::Nodes::Local
Local
node definition, implements the {RJR::Node} interface to listen for and invoke json-rpc requests via local handlers
This is useful for situations in which you would like to invoke registered json-rpc handlers locally, enforcing the same constraints as you would on a json-rpc request coming in remotely.
Note this only dispatches to the methods defined on the local dispatcher!
If you have two local nodes, they will have seperate dispatchers unless you assign them the same object (eg node2.dispatcher = node1.dispatcher or node2 = new RJR::Nodes::Local.new
(:dispatcher :=> node1.dispatcher))
@example Listening for and dispatching json-rpc requests locally
# initialize node node = RJR::Nodes::Local.new :node_id => 'node' node.dispatcher.handle('hello') do |name| @rjr_node_type == :local ? "Hello superuser #{name}" : "Hello #{name}!" end # invoke request node.invoke('hello', 'mo')
Constants
- INDIRECT_NODE
- PERSISTENT_NODE
- RJR_NODE_TYPE
Attributes
allows clients to override the node type for the local node
Public Class Methods
Nodes::Local
initializer @param [Hash] args the options to create the local node with
RJR::Node::new
# File lib/rjr/nodes/local.rb, line 48 def initialize(args = {}) super(args) @node_type = RJR_NODE_TYPE end
Public Instance Methods
Instructs node to send rpc request, and wait for and return response
Implementation of RJR::Node#invoke
If strictly confirming to other nodes, this would use event machine to launch a thread pool job to dispatch request and block on result. Optimized for performance reasons but recognize that the semantics of using the local node will be somewhat different.
@param [String] rpc_method json-rpc method to invoke on destination @param [Array] args array of arguments to convert to json and invoke remote method with @return [Object] the json result retrieved from destination converted to a ruby object @raise [Exception] if the destination raises an exception, it will be converted to json and re-raised here
# File lib/rjr/nodes/local.rb, line 109 def invoke(rpc_method, *args) 0.upto(args.size).each { |i| args[i] = args[i].to_s if args[i].is_a?(Symbol) } message = Messages::Request.new(:method => rpc_method, :args => args, :headers => @message_headers) launch_request(message.to_s, false) # TODO optional timeout for response ? res = wait_for_result(message) if res.size > 2 fail res[2] end return res[1] end
Helper to launch request in new thread
This needs to happen so that each request runs in its own context (or close to it, globals will still be available, but locks will
not be locally held, etc)
# File lib/rjr/nodes/local.rb, line 83 def launch_request(req, notification) Thread.new(req, notification) { |req, notification| inter = req.is_a?(Messages::Intermediate) ? req : Messages::Intermediate.parse(req) res = handle_request(inter, notification, nil) unless res.nil? inter = Messages::Intermediate.parse(res.to_s) handle_response(inter) end } end
Instruct Nodes
to start listening for and dispatching rpc requests
Implementation of RJR::Node#listen
# File lib/rjr/nodes/local.rb, line 73 def listen # do nothing self end
Instructs node to send rpc notification (immediately returns / no response is generated)
Implementation of RJR::Node#notify
Same performance comment as invoke_request above
@param [String] rpc_method json-rpc method to invoke on destination @param [Array] args array of arguments to convert to json and invoke remote method wtih
# File lib/rjr/nodes/local.rb, line 133 def notify(rpc_method, *args) 0.upto(args.size).each { |i| args[i] = args[i].to_s if args[i].is_a?(Symbol) } message = Messages::Notification.new(:method => rpc_method, :args => args, :headers => @message_headers) launch_request(message.to_s, true) #.join ? nil end
Send data using specified connection.
Simply dispatch local notification.
Implementation of RJR::Node#send_msg
# File lib/rjr/nodes/local.rb, line 62 def send_msg(msg, connection) # ignore response message inter = Messages::Intermediate.parse(msg) unless Messages::Response.is_response_message?(inter) launch_request(inter, true) # .join? end end
# File lib/rjr/nodes/local.rb, line 53 def to_s "RJR::Nodes::Local<#{@node_id}>" end