Class: Zold::Remotes

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

Overview

All remotes

Defined Under Namespace

Classes: Empty

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

8
MAX_NODES =

Default number of nodes to fetch.

16

Instance Method Summary collapse

Constructor Details

#initialize(file:, network: 'test', timeout: 60) ⇒ Remotes

Returns a new instance of Remotes.



153
154
155
156
157
# File 'lib/zold/remotes.rb', line 153

def initialize(file:, network: 'test', timeout: 60)
  @file = file
  @network = network
  @timeout = timeout
end

Instance Method Details

#add(host, port = PORT) ⇒ Object



189
190
191
192
193
194
195
# 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

#allObject



159
160
161
162
163
164
165
166
167
168
# 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

#cleanObject



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

def clean
  modify { [] }
end

#error(host, port = PORT) ⇒ Object



239
240
241
242
# 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) ⇒ Boolean

Returns:

  • (Boolean)


183
184
185
186
187
# 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) ⇒ Object

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.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# 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) ⇒ Boolean

Returns:

  • (Boolean)


263
264
265
# File 'lib/zold/remotes.rb', line 263

def master?(host, port)
  !MASTERS.find { |r| r[:host] == host && r[:port] == port }.nil?
end

#mastersObject



174
175
176
177
178
179
180
181
# 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

#mtimeObject



259
260
261
# File 'lib/zold/remotes.rb', line 259

def mtime
  File.exist?(@file) ? File.mtime(@file) : Time.now
end

#remove(host, port = PORT) ⇒ Object



197
198
199
200
201
202
# 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) ⇒ Object



251
252
253
254
255
256
257
# 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) ⇒ Object



244
245
246
247
248
249
# 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