class Arachni::RPC::Server::Dispatcher::SERVICE_NAMESPACE
Base
class and namespace for all Dispatcher
services.
# 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.
@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>
Attributes
Public Class Methods
# File lib/arachni/rpc/server/dispatcher/service.rb, line 42 def initialize( options, dispatcher ) @options = options @dispatcher = dispatcher end
Public Instance Methods
Connects to a Dispatcher by ‘url`
@param [String] url
@return [Client::Dispatcher]
# File lib/arachni/rpc/server/dispatcher/service.rb, line 121 def connect_to_dispatcher( url ) @dispatcher_connections ||= {} @dispatcher_connections[url] ||= Client::Dispatcher.new( options, url ) end
Connects to an Instance by ‘url`.
@example
connect_to_instance( url, token ) connect_to_instance( url: url, token: token ) connect_to_instance( 'url' => url, 'token' => token )
@param [Vararg] args
@return [Client::Instance]
# File lib/arachni/rpc/server/dispatcher/service.rb, line 136 def connect_to_instance( *args ) url = token = nil if args.size == 2 url, token = *args elsif args.first.is_a? Hash connection_options = args.first url = connection_options['url'] || connection_options[:url] token = connection_options['token'] || connection_options[:token] end @instance_connections ||= {} @instance_connections[url] ||= Client::Instance.new( options, url, token ) end
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.
@param [Proc] operation
Operation to defer.
@param [Proc] callback
Block to call with the results of the operation.
@param [Block] block
Operation to defer.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 91 def defer( operation = nil, callback = nil, &block ) Thread.new( *[operation, callback].compact, &block ) end
Performs an asynchronous iteration over all running instances.
@param [Proc] block
Block to be passed {Client::Instance} and `Arachni::Reactor::Iterator`.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 70 def each_instance( &block ) wrap = proc do |instance, iterator| block.call( connect_to_instance( instance ), iterator ) end iterator_for( instances ).each( &wrap ) end
@return [Array<Hash>]
Alive instances.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 112 def instances dispatcher.running_jobs end
@param [Array] list
@return [Reactor::Iterator]
Iterator for the provided array.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 106 def iterator_for( list, max_concurrency = 10 ) Reactor.global.create_iterator( list, max_concurrency ) end
Performs an asynchronous map operation over all running instances.
@param [Proc] each
Block to be passed {Client::Instance} and `Arachni::Reactor::Iterator`.
@param [Proc] after
Block to be passed the Array of results.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 59 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
@return [Server::Dispatcher::Node]
Local node.
# File lib/arachni/rpc/server/dispatcher/service.rb, line 49 def node dispatcher.instance_eval { @node } end
Runs a block as soon as possible in the Reactor loop.
@param [Block] block
# File lib/arachni/rpc/server/dispatcher/service.rb, line 98 def run_asap( &block ) Reactor.global.next_tick( &block ) end