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.



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

def initialize(file)
  @file = file
end

Instance Method Details

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



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

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



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

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



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

def clean
  save([])
end

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



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

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



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

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)


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

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



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

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(Backtrace.new(e).to_s)
      remove(r[:host], r[:port]) if errors > Remotes::TOLERANCE
    end
  end
end

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



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

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



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

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



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

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