Class: Arachni::RPC::Server::Dispatcher::Handler
- Defined in:
- lib/arachni/rpc/server/dispatcher/handler.rb
Overview
Base class and namespace for all RPCD/Dispatcher handlers.
# RPC accessibility
Only PUBLIC methods YOU have defined will be accessible over RPC.
# Blocking operations
Please try to avoid blocking operations as they will block the main Reactor loop.
However, if you really need to perform such operations, you can update the relevant methods to expect a block and then pass the desired return value to that block instead of returning it the usual way.
This will result in the method’s payload to be deferred into a Thread of its own.
In addition, you can use the #defer and #run_asap methods is you need more control over what gets deferred and general scheduling.
# Asynchronous operations
Methods which perform async operations should expect a block and pass their results to that block instead of returning a value.
Instance Attribute Summary collapse
-
#dispatcher ⇒ Object
readonly
Returns the value of attribute dispatcher.
-
#opts ⇒ Object
readonly
Returns the value of attribute opts.
Instance Method Summary collapse
-
#connect_to_dispatcher(url) ⇒ Client::Dispatcher
Connects to a Dispatcher by ‘url`.
-
#connect_to_instance(*args) ⇒ Client::Instance
Connects to an Instance by ‘url`.
-
#defer(operation = nil, callback = nil, &block) ⇒ Object
Defers a blocking operation in order to avoid blocking the main Reactor loop.
-
#each_instance(&block) ⇒ Object
Performs an asynchronous iteration over all running instances.
-
#initialize(opts, dispatcher) ⇒ Handler
constructor
A new instance of Handler.
-
#instances ⇒ Array<Hash>
All running instances.
-
#iterator_for(arr, max_concurrency = 10) ⇒ ::EM::Iterator
Iterator for the provided array.
-
#map_instances(each, after) ⇒ Object
Performs an asynchronous map operation over all running instances.
-
#node ⇒ Server::Dispatcher::Node
Local node.
-
#run_asap(&block) ⇒ Object
Runs a block as soon as possible in the Reactor loop.
Constructor Details
#initialize(opts, dispatcher) ⇒ Handler
Returns a new instance of Handler.
51 52 53 54 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 51 def initialize( opts, dispatcher ) @opts = opts @dispatcher = dispatcher end |
Instance Attribute Details
#dispatcher ⇒ Object (readonly)
Returns the value of attribute dispatcher.
49 50 51 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 49 def dispatcher @dispatcher end |
#opts ⇒ Object (readonly)
Returns the value of attribute opts.
48 49 50 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 48 def opts @opts end |
Instance Method Details
#connect_to_dispatcher(url) ⇒ Client::Dispatcher
Connects to a Dispatcher by ‘url`
133 134 135 136 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 133 def connect_to_dispatcher( url ) @dispatcher_connections ||= {} @dispatcher_connections[url] ||= Client::Dispatcher.new( opts, url ) end |
#connect_to_instance(*args) ⇒ Client::Instance
Connects to an Instance by ‘url`.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 150 def connect_to_instance( *args ) url = token = nil if args.size == 2 url, token = *args elsif args.first.is_a? Hash = args.first url = ['url'] || [:url] token = ['token'] || [:token] end @instance_connections ||= {} @instance_connections[url] ||= Client::Instance.new( opts, url, token ) end |
#defer(operation = nil, callback = nil, &block) ⇒ Object
Defers a blocking operation in order to avoid blocking the main Reactor loop.
The operation will be run in its own Thread - DO NOT block forever.
Accepts either 2 parameters (an ‘operation` and a `callback` or an operation as a block.
99 100 101 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 99 def defer( operation = nil, callback = nil, &block ) ::EM.defer( *[operation, callback].compact, &block ) end |
#each_instance(&block) ⇒ Object
Performs an asynchronous iteration over all running instances.
79 80 81 82 83 84 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 79 def each_instance( &block ) wrap = proc do |instance, iterator| block.call( connect_to_instance( instance ), iterator ) end iterator_for( instances ).each( &wrap ) end |
#instances ⇒ Array<Hash>
Returns All running instances.
122 123 124 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 122 def instances dispatcher.jobs.select { |j| !j['proc'].empty? } end |
#iterator_for(arr, max_concurrency = 10) ⇒ ::EM::Iterator
Returns Iterator for the provided array.
117 118 119 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 117 def iterator_for( arr, max_concurrency = 10 ) ::EM::Iterator.new( arr, max_concurrency ) end |
#map_instances(each, after) ⇒ Object
Performs an asynchronous map operation over all running instances.
67 68 69 70 71 72 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 67 def map_instances( each, after ) wrap_each = proc do |instance, iterator| each.call( connect_to_instance( instance ), iterator ) end iterator_for( instances ).map( wrap_each, after ) end |
#node ⇒ Server::Dispatcher::Node
Returns Local node.
57 58 59 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 57 def node dispatcher.instance_eval { @node } end |
#run_asap(&block) ⇒ Object
Runs a block as soon as possible in the Reactor loop.
108 109 110 |
# File 'lib/arachni/rpc/server/dispatcher/handler.rb', line 108 def run_asap( &block ) ::EM.next_tick( &block ) end |