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.
Constant Summary collapse
- DEFAULT_PING_INTERVAL =
60
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(opts, 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, #error_logfile, #flush_buffer, #log_error, #mute, #muted?, old_reset_output_options, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_pp, #print_error, #print_error_backtrace, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #set_buffer_cap, #set_error_logfile, #uncap_buffer, #unmute, #verbose, #verbose?
Constructor Details
#initialize(opts, 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.
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 80 81 82 83 84 85 86 87 88 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 53 def initialize( opts, logfile = nil ) @opts = opts @opts.rpc_external_address ||= @opts.rpc_address @url = "#{@opts.rpc_external_address}:#{@opts.rpc_port}" reroute_to_file( logfile ) if logfile print_status 'Initializing grid node...' @dead_nodes = [] @neighbours = Set.new @nodes_info_cache = [] if (neighbour = @opts.neighbour) # add neighbour and announce him to everyone add_neighbour( neighbour, true ) # grab the neighbour's neighbours peer = connect_to_peer( neighbour ) peer.neighbours do |urls| fail "Neighbour '#{neighbour}' is unreachable." if urls.rpc_exception? urls.each { |url| @neighbours << url if url != @url } end end print_status( 'Node ready.' ) log_updated_neighbours interval = @opts.node_ping_interval || DEFAULT_PING_INTERVAL ::EM.add_periodic_timer( 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.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 102 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
175 176 177 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 175 def alive? true end |
#grid_member? ⇒ Boolean
Returns ‘true` if grid member, `false` otherwise.
91 92 93 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 91 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.
165 166 167 168 169 170 171 172 173 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 165 def info { 'url' => @url, 'pipe_id' => @opts.pipe_id, 'weight' => @opts.weight, 'nickname' => @opts.nickname, 'cost' => @opts.cost } end |
#neighbours ⇒ Array
Returns Neighbour/node/peer URLs.
122 123 124 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 122 def neighbours @neighbours.to_a end |
#neighbours_with_info(&block) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/arachni/rpc/server/dispatcher/node.rb', line 126 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 ::EM::Iterator.new( neighbours ).map( each, after ) else block.call( @nodes_info_cache ) end end |