lib/zold/commands/remote.rb in zold-0.21.4 vs lib/zold/commands/remote.rb in zold-0.22.0
- old
+ new
@@ -91,16 +91,22 @@
'Ignore this node and never add it to the list',
default: []
o.bool '--ignore-if-exists',
'Ignore the node while adding if it already exists in the list',
default: false
+ o.bool '--ignore-masters',
+ 'Don\'t elect master nodes, only edges',
+ default: false
o.integer '--min-score',
"The minimum score required for winning the election (default: #{Tax::EXACT_SCORE})",
default: Tax::EXACT_SCORE
o.integer '--max-winners',
'The maximum amount of election winners the election (default: 1)',
default: 1
+ o.integer '--retry',
+ 'How many times to retry each node before reporting a failure (default: 2)',
+ default: 2
o.bool '--skip-ping',
'Don\'t ping back the node when adding it (not recommended)',
default: false
o.bool '--ignore-ping',
'Don\'t fail if ping fails, just report the problem in the log',
@@ -225,10 +231,14 @@
score = Score.parse_json(json['score'])
r.assert_valid_score(score)
r.assert_score_ownership(score)
r.assert_score_strength(score) unless opts['ignore-score-weakness']
r.assert_score_value(score, opts['min-score']) unless opts['ignore-score-value']
+ if r.master? && opts['--ignore-masters']
+ @log.debug("#{r} ignored, it's a master node")
+ next
+ end
scores << score
end
scores = scores.sample(opts['max-winners'])
if scores.empty?
@log.info("No winners elected out of #{@remotes.all.count} remotes")
@@ -252,45 +262,42 @@
st = Time.now
capacity = []
opts['depth'].times do |cycle|
@remotes.iterate(@log, farm: @farm) do |r|
start = Time.now
- uri = '/remotes'
- res = r.http(uri).get
- r.assert_code(200, res)
- json = JsonPage.new(res.body, uri).to_hash
- score = Score.parse_json(json['score'])
- r.assert_valid_score(score)
- r.assert_score_ownership(score)
- r.assert_score_strength(score) unless opts['ignore-score-weakness']
- @remotes.rescore(score.host, score.port, score.value)
- if Semantic::Version.new(VERSION) < Semantic::Version.new(json['version'])
- if opts['reboot']
- @log.info("#{r}: their version #{json['version']} is higher than mine #{VERSION}, reboot! \
-(use --never-reboot to avoid this from happening)")
- terminate
+ update_one(r, opts) do |json, score|
+ r.assert_valid_score(score)
+ r.assert_score_ownership(score)
+ r.assert_score_strength(score) unless opts['ignore-score-weakness']
+ @remotes.rescore(score.host, score.port, score.value)
+ if Semantic::Version.new(VERSION) < Semantic::Version.new(json['version'])
+ if opts['reboot']
+ @log.info("#{r}: their version #{json['version']} is higher than mine #{VERSION}, reboot! \
+ (use --never-reboot to avoid this from happening)")
+ terminate
+ end
+ @log.debug("#{r}: their version #{json['version']} is higher than mine #{VERSION}, \
+ it's recommended to reboot, but I don't do it because of --never-reboot")
end
- @log.debug("#{r}: their version #{json['version']} is higher than mine #{VERSION}, \
-it's recommended to reboot, but I don't do it because of --never-reboot")
- end
- if Semantic::Version.new(VERSION) < Semantic::Version.new(Zold::Gem.new.last_version)
- if opts['reboot']
- @log.info("#{r}: the version of the gem is higher than mine #{VERSION}, reboot! \
-(use --never-reboot to avoid this from happening)")
- terminate
+ if Semantic::Version.new(VERSION) < Semantic::Version.new(Zold::Gem.new.last_version)
+ if opts['reboot']
+ @log.info("#{r}: the version of the gem is higher than mine #{VERSION}, reboot! \
+ (use --never-reboot to avoid this from happening)")
+ terminate
+ end
+ @log.debug("#{r}: gem version is higher than mine #{VERSION}, \
+ it's recommended to reboot, but I don't do it because of --never-reboot")
end
- @log.debug("#{r}: gem version is higher than mine #{VERSION}, \
-it's recommended to reboot, but I don't do it because of --never-reboot")
- end
- if cycle.positive?
- json['all'].each do |s|
- next if @remotes.exists?(s['host'], s['port'])
- add(s['host'], s['port'], opts)
+ if cycle.positive?
+ json['all'].each do |s|
+ next if @remotes.exists?(s['host'], s['port'])
+ add(s['host'], s['port'], opts)
+ end
end
+ capacity << { host: score.host, port: score.port, count: json['all'].count }
+ @log.info("#{r}: the score is #{Rainbow(score.value).green} (#{json['version']}) in #{Age.new(start)}")
end
- capacity << { host: score.host, port: score.port, count: json['all'].count }
- @log.info("#{r}: the score is #{Rainbow(score.value).green} (#{json['version']}) in #{Age.new(start)}")
end
end
max_capacity = capacity.map { |c| c[:count] }.max || 0
capacity.each do |c|
@remotes.error(c[:host], c[:port]) if c[:count] < max_capacity
@@ -299,9 +306,28 @@
if total.zero?
@log.info("The list of remotes is #{Rainbow('empty').red}, run 'zold remote reset'!")
else
@log.info("There are #{total} known remotes with the overall score of \
#{@remotes.all.map { |r| r[:score] }.inject(&:+)}, after update in #{Age.new(st)}")
+ end
+ end
+
+ def update_one(r, opts)
+ attempt = 0
+ begin
+ uri = '/remotes'
+ res = r.http(uri).get
+ r.assert_code(200, res)
+ json = JsonPage.new(res.body, uri).to_hash
+ score = Score.parse_json(json['score'])
+ yield json, score
+ rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
+ attempt += 1
+ if attempt < opts['retry']
+ @log.error("#{r} failed to read #{id}, trying again (attempt no.#{attempt}): #{e.message}")
+ retry
+ end
+ raise e
end
end
def select(opts)
selected = @remotes.all.sort_by { |r| r[:score] }.reverse.first(opts['max-nodes'])