Class: Arachni::RPC::Server::Dispatcher::Node
- Includes:
- UI::Output
- Defined in:
- lib/arachni/rpc/server/dispatcher/node.rb
Overview
Dispatcher node class, helps maintain a list of all available Dispatchers in the grid and announce itself to neighbouring Dispatchers.
As soon as a new Node is fired up it checks-in with its neighbour and grabs a list of all available peers.
As soon as it receives the peer list it then announces itself to them.
Upon convergence there will be a grid of Dispatchers each one with its own copy of all available Dispatcher URLs.
Instance Method Summary collapse
-
#add_neighbour(node_url, propagate = false) ⇒ Object
Adds a neighbour to the peer list.
- #alive? ⇒ Boolean
-
#grid_member? ⇒ Boolean
‘true` if grid member, `false` otherwise.
-
#info ⇒ Hash
-
‘url` – This node’s URL.
-
-
#initialize(options, logfile = nil) ⇒ Node
constructor
Initializes the node by:.
-
#neighbours ⇒ Array
Neighbour/node/peer URLs.
- #neighbours_with_info(&block) ⇒ Object
Methods included from UI::Output
#debug?, #debug_off, #debug_on, #disable_only_positives, #included, #mute, #muted?, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_level_1, #print_debug_level_2, #print_debug_level_3, #print_error, #print_error_backtrace, #print_exception, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #unmute, #verbose?, #verbose_on
Constructor Details
#initialize(options, logfile = nil) ⇒ Node
Initializes the node by:
* Adding the neighbour (if the user has supplied one) to the peer list.
* Getting the neighbour's peer list and appending them to its own.
* Announces itself to the neighbour and instructs it to propagate our URL
to the others.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 40 def initialize( , logfile = nil ) @options = @options.dispatcher.external_address ||= @options.rpc.server_address @url = "#{@options.dispatcher.external_address}:#{@options.rpc.server_port}" reroute_to_file( logfile ) if logfile print_status 'Initializing grid node...' @dead_nodes = [] @neighbours = Set.new @nodes_info_cache = [] if (neighbour = @options.dispatcher.neighbour) # Grab the neighbour's neighbours. connect_to_peer( neighbour ).neighbours do |urls| if urls.rpc_exception? add_dead_neighbour( neighbour ) print_info "Neighbour seems dead: #{neighbour}" add_dead_neighbour( neighbour ) next end # Add neighbour and announce it to everyone. add_neighbour( neighbour, true ) urls.each { |url| @neighbours << url if url != @url } end end print_status( 'Node ready.' ) log_updated_neighbours Reactor.global.at_interval( @options.dispatcher.node_ping_interval ) do ping check_for_comebacks end end |
Instance Method Details
#add_neighbour(node_url, propagate = false) ⇒ Object
Adds a neighbour to the peer list.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 93 def add_neighbour( node_url, propagate = false ) # we don't want ourselves in the Set return false if node_url == @url return false if @neighbours.include?( node_url ) print_status "Adding neighbour: #{node_url}" @neighbours << node_url log_updated_neighbours announce( node_url ) if propagate connect_to_peer( node_url ).add_neighbour( @url, propagate ) do |res| next if !res.rpc_exception? add_dead_neighbour( node_url ) print_status "Neighbour seems dead: #{node_url}" end true end |
#alive? ⇒ Boolean
168 169 170 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 168 def alive? true end |
#grid_member? ⇒ Boolean
Returns ‘true` if grid member, `false` otherwise.
83 84 85 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 83 def grid_member? @neighbours.any? end |
#info ⇒ Hash
Returns * ‘url` – This node’s URL.
-
‘pipe_id` – Bandwidth Pipe ID
-
‘weight` – Weight
-
‘nickname` – Nickname
-
‘cost` – Cost.
158 159 160 161 162 163 164 165 166 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 158 def info { 'url' => @url, 'pipe_id' => @options.dispatcher.node_pipe_id, 'weight' => @options.dispatcher.node_weight, 'nickname' => @options.dispatcher.node_nickname, 'cost' => @options.dispatcher.node_cost } end |
#neighbours ⇒ Array
Returns Neighbour/node/peer URLs.
114 115 116 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 114 def neighbours @neighbours.to_a end |
#neighbours_with_info(&block) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 118 def neighbours_with_info( &block ) fail 'This method requires a block!' if !block_given? @neighbours_cmp = '' if @nodes_info_cache.empty? || @neighbours_cmp != neighbours.to_s @neighbours_cmp = neighbours.to_s each = proc do |neighbour, iter| connect_to_peer( neighbour ).info do |info| if info.rpc_exception? print_info "Neighbour seems dead: #{neighbour}" add_dead_neighbour( neighbour ) log_updated_neighbours iter.return( nil ) else iter.return( info ) end end end after = proc do |nodes| @nodes_info_cache = nodes.compact block.call( @nodes_info_cache ) end Reactor.global.create_iterator( neighbours ).map( each, after ) else block.call( @nodes_info_cache ) end end |