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.



135
136
137
138
139
# File 'lib/zold/remotes.rb', line 135

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

Instance Method Details

#add(host, port = PORT) ⇒ Object



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

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



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

def all
  list = Futex.new(@file).open(false) { 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



152
153
154
# File 'lib/zold/remotes.rb', line 152

def clean
  modify { [] }
end

#error(host, port = PORT) ⇒ Object



217
218
219
220
# File 'lib/zold/remotes.rb', line 217

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)


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

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) ⇒ 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.



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/zold/remotes.rb', line 189

def iterate(log, farm: Farm::Empty.new)
  raise 'Log can\'t be nil' if log.nil?
  raise 'Farm can\'t be nil' if farm.nil?
  Hands.exec(Concurrent.processor_count * 4, all) do |r, idx|
    Thread.current.name = "remotes-#{idx}@#{r[:host]}:#{r[:port]}"
    start = Time.now
    best = farm.best[0]
    begin
      yield 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
      )
      raise 'Took too long to execute' if (Time.now - start).round > @timeout
      unerror(r[:host], r[:port])
    rescue StandardError => e
      error(r[:host], r[:port])
      log.info("#{Rainbow("#{r[:host]}:#{r[:port]}").red}: #{e.message} in #{Age.new(start)}")
      log.debug(Backtrace.new(e).to_s)
      remove(r[:host], r[:port]) if r[:errors] > TOLERANCE
    end
  end
end

#master?(host, port) ⇒ Boolean

Returns:

  • (Boolean)


242
243
244
# File 'lib/zold/remotes.rb', line 242

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

#mastersObject



156
157
158
159
160
161
162
163
# File 'lib/zold/remotes.rb', line 156

def masters
  MASTERS.each do |r|
    if block_given?
      next unless yield(r[0], r[1].to_i)
    end
    add(r[0], r[1].to_i)
  end
end

#mtimeObject



238
239
240
# File 'lib/zold/remotes.rb', line 238

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

#remove(host, port = PORT) ⇒ Object



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

def remove(host, port = PORT)
  assert_host_info(host, port)
  modify do |list|
    list.reject { |r| r[:host] == host.downcase && r[:port] == port }
  end
  unerror(host, port)
end

#rescore(host, port, score) ⇒ Object



230
231
232
233
234
235
236
# File 'lib/zold/remotes.rb', line 230

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



222
223
224
225
226
227
228
# File 'lib/zold/remotes.rb', line 222

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