class Zold::Remotes
All remotes
Constants
- MASTERS
Default nodes and their ports
- MAX_NODES
Default number of nodes to fetch.
- PORT
The default TCP port all nodes are supposed to use.
- TOLERANCE
At what amount of errors we delete the remote automatically
Public Class Methods
new(file:, network: 'test', timeout: 60)
click to toggle source
# File lib/zold/remotes.rb, line 153 def initialize(file:, network: 'test', timeout: 60) @file = file @network = network @timeout = timeout end
Public Instance Methods
add(host, port = PORT)
click to toggle source
# File lib/zold/remotes.rb, line 189 def add(host, port = PORT) assert_host_info(host, port) modify do |list| list + [{ host: host.downcase, port: port, score: 0, errors: 0 }] end unerror(host, port) end
all()
click to toggle source
# File lib/zold/remotes.rb, line 159 def all list = Futex.new(@file).open(false) { load } max_score = list.empty? ? 0 : list.max_by { |r| r[:score] }[:score] max_score = 1 if max_score.zero? max_errors = list.empty? ? 0 : list.max_by { |r| r[:errors] }[:errors] max_errors = 1 if max_errors.zero? list.sort_by do |r| (1 - r[:errors] / max_errors) * 5 + (r[:score] / max_score) end.reverse end
clean()
click to toggle source
# File lib/zold/remotes.rb, line 170 def clean modify { [] } end
error(host, port = PORT)
click to toggle source
# File lib/zold/remotes.rb, line 239 def error(host, port = PORT) assert_host_info(host, port) if_present(host, port) { |r| r[:errors] += 1 } end
exists?(host, port = PORT)
click to toggle source
# File lib/zold/remotes.rb, line 183 def exists?(host, port = PORT) assert_host_info(host, port) list = Futex.new(@file).open(false) { load } !list.find { |r| r[:host] == host.downcase && r[:port] == port }.nil? end
iterate(log, farm: Farm::Empty.new, threads: 1) { |node| ... }
click to toggle source
Go through the list of remotes and call a provided block for each of them. See how it's used, for example, in fetch.rb.
# File lib/zold/remotes.rb, line 206 def iterate(log, farm: Farm::Empty.new, threads: 1) raise 'Log can\'t be nil' if log.nil? raise 'Farm can\'t be nil' if farm.nil? Hands.exec(threads, all) do |r, idx| Thread.current.name = "remotes-#{idx}@#{r[:host]}:#{r[:port]}" start = Time.now best = farm.best[0] node = RemoteNode.new( host: r[:host], port: r[:port], score: best.nil? ? Score::ZERO : best, idx: idx, master: master?(r[:host], r[:port]), log: log, network: @network ) begin yield node raise 'Took too long to execute' if (Time.now - start).round > @timeout unerror(r[:host], r[:port]) if node.touched rescue StandardError => e error(r[:host], r[:port]) if e.is_a?(RemoteNode::CantAssert) || e.is_a?(Fetch::Error) log.debug("#{Rainbow(node).red}: \"#{e.message.strip}\" in #{Age.new(start)}") else log.info("#{Rainbow(node).red}: \"#{e.message.strip}\" in #{Age.new(start)}") log.debug(Backtrace.new(e).to_s) end remove(r[:host], r[:port]) if r[:errors] > TOLERANCE end end end
master?(host, port)
click to toggle source
# File lib/zold/remotes.rb, line 263 def master?(host, port) !MASTERS.find { |r| r[:host] == host && r[:port] == port }.nil? end
masters() { |r, r| ... }
click to toggle source
# File lib/zold/remotes.rb, line 174 def masters MASTERS.each do |r| if block_given? next unless yield(r[:host], r[:port]) end add(r[:host], r[:port]) end end
mtime()
click to toggle source
# File lib/zold/remotes.rb, line 259 def mtime File.exist?(@file) ? File.mtime(@file) : Time.now end
remove(host, port = PORT)
click to toggle source
# File lib/zold/remotes.rb, line 197 def remove(host, port = PORT) assert_host_info(host, port) modify do |list| list.reject { |r| r[:host] == host.downcase && r[:port] == port } end end
rescore(host, port, score)
click to toggle source
# File lib/zold/remotes.rb, line 251 def rescore(host, port, score) assert_host_info(host, port) raise 'Score can\'t be nil' if score.nil? raise 'Score has to be of type Integer' unless score.is_a?(Integer) if_present(host, port) { |r| r[:score] = score } unerror(host, port) end
unerror(host, port = PORT)
click to toggle source
# File lib/zold/remotes.rb, line 244 def unerror(host, port = PORT) assert_host_info(host, port) if_present(host, port) do |remote| remote[:errors] -= 1 if (remote[:errors]).positive? end end
Private Instance Methods
assert_host_info(host, port)
click to toggle source
# File lib/zold/remotes.rb, line 316 def assert_host_info(host, port) raise 'Host can\'t be nil' if host.nil? raise 'Host can\'t be empty' if host.empty? raise 'Host IP is wrong, can\'t be all zeros' if host == '0.0.0.0' raise 'Port can\'t be nil' if port.nil? raise 'Port has to be of type Integer' unless port.is_a?(Integer) raise 'Port can\'t be zero' if port.zero? raise 'Port can\'t be negative' if port.negative? raise 'Port can\'t be over 65536' if port > 0xffff end
if_present(host, port) { |remote| ... }
click to toggle source
# File lib/zold/remotes.rb, line 287 def if_present(host, port) modify do |list| remote = list.find { |r| r[:host] == host.downcase && r[:port] == port } return unless remote yield remote list end end
load()
click to toggle source
# File lib/zold/remotes.rb, line 296 def load if File.exist?(@file) raw = CSV.read(@file).map do |row| { host: row[0], port: row[1].to_i, score: row[2].to_i, errors: row[3].to_i, master: master?(row[0], row[1].to_i) } end raw.reject { |r| !r[:host] || r[:port].zero? || r[:host] == '0.0.0.0' }.map do |r| r[:home] = URI("http://#{r[:host]}:#{r[:port]}/") r end else [] end end
modify() { |load| ... }
click to toggle source
# File lib/zold/remotes.rb, line 269 def modify FileUtils.mkdir_p(File.dirname(@file)) Futex.new(@file).open do list = yield(load) IO.write( @file, list.uniq { |r| "#{r[:host]}:#{r[:port]}" }.map do |r| [ r[:host], r[:port], r[:score], r[:errors] ].join(',') end.join("\n") ) end end