Class: Zold::Remotes

Inherits:
Object
  • Object
show all
Defined in:
lib/zold/remotes.rb

Overview

All remotes

Defined Under Namespace

Classes: Empty, Remote

Constant Summary collapse

PORT =

The default TCP port all nodes are supposed to use.

4096
TOLERANCE =

At what amount of errors we delete the remote automatically

50

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ Remotes

Returns a new instance of Remotes.



98
99
100
# File 'lib/zold/remotes.rb', line 98

def initialize(file)
  @file = file
end

Instance Method Details

#add(host, port = Remotes::PORT) ⇒ Object



130
131
132
133
134
135
136
137
138
139
# File 'lib/zold/remotes.rb', line 130

def add(host, port = Remotes::PORT)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  raise 'Port can\'t be negative' if port < 0
  raise 'Port can\'t be over 65536' if port > 0xffff
  raise "#{host}:#{port} already exists" if exists?(host, port)
  list = load
  list << { host: host.downcase, port: port, score: 0 }
  list.uniq! { |r| "#{r[:host]}:#{r[:port]}" }
  save(list)
end

#allObject



102
103
104
105
106
107
108
109
110
111
# File 'lib/zold/remotes.rb', line 102

def all
  list = load
  max_score = list.map { |r| r[:score] }.max || 0
  max_score = 1 if max_score.zero?
  max_errors = list.map { |r| r[:errors] }.max || 0
  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

#cleanObject



113
114
115
# File 'lib/zold/remotes.rb', line 113

def clean
  save([])
end

#error(host, port = Remotes::PORT) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/zold/remotes.rb', line 173

def error(host, port = Remotes::PORT)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  list = load
  raise "#{host}:#{port} is absent among #{list.count} remotes" unless exists?(host, port)
  list.find { |r| r[:host] == host.downcase && r[:port] == port }[:errors] += 1
  save(list)
end

#errors(host, port = Remotes::PORT) ⇒ Object



166
167
168
169
170
171
# File 'lib/zold/remotes.rb', line 166

def errors(host, port = Remotes::PORT)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  list = load
  raise "#{host}:#{port} is absent among #{list.count} remotes" unless exists?(host, port)
  list.find { |r| r[:host] == host.downcase && r[:port] == port }[:errors]
end

#exists?(host, port = Remotes::PORT) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
# File 'lib/zold/remotes.rb', line 125

def exists?(host, port = Remotes::PORT)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  !load.find { |r| r[:host] == host.downcase && r[:port] == port }.nil?
end

#iterate(log, farm: Farm::Empty.new) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/zold/remotes.rb', line 149

def iterate(log, farm: Farm::Empty.new)
  best = farm.best[0]
  require_relative 'score'
  score = best.nil? ? Score::ZERO : best
  all.each do |r|
    begin
      yield Remotes::Remote.new(r[:host], r[:port], score, log: log)
    rescue StandardError => e
      error(r[:host], r[:port])
      errors = errors(r[:host], r[:port])
      log.info("#{Rainbow("#{r[:host]}:#{r[:port]}").red}: #{e.message}; errors=#{errors}")
      log.debug(e.backtrace[0..5].join("\n\t"))
      remove(r[:host], r[:port]) if errors > Remotes::TOLERANCE
    end
  end
end

#remove(host, port = Remotes::PORT) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/zold/remotes.rb', line 141

def remove(host, port = Remotes::PORT)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  raise "#{host}:#{port} is absent" unless exists?(host, port)
  list = load
  list.reject! { |r| r[:host] == host.downcase && r[:port] == port }
  save(list)
end

#rescore(host, port, score) ⇒ Object



181
182
183
184
185
186
187
# File 'lib/zold/remotes.rb', line 181

def rescore(host, port, score)
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
  raise "#{host}:#{port} is absent" unless exists?(host, port)
  list = load
  list.find { |r| r[:host] == host.downcase && r[:port] == port }[:score] = score
  save(list)
end

#resetObject



117
118
119
120
121
122
123
# File 'lib/zold/remotes.rb', line 117

def reset
  FileUtils.mkdir_p(File.dirname(@file))
  FileUtils.copy(
    File.join(File.dirname(__FILE__), '../../resources/remotes'),
    @file
  )
end