zold 0.13.22 → 0.13.23

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2e4d4e5e627137b421211b093b25dd2930423d7
4
- data.tar.gz: e78835ebe8c5ead373287def6500d3d17a9ab648
3
+ metadata.gz: b063b1f42e4e318877c41c1281df5ece0c0a61c4
4
+ data.tar.gz: 8b42936d634c08e26c3b3381c296a9de9cd28ec3
5
5
  SHA512:
6
- metadata.gz: e0d902fe84aa485c17b9785d83a832ca212c001db35bedd520026d1f4bc41e162006b3aecc3459192a9d5d24e6bfdbcd7a157edb871695b34fe663c816f35f6c
7
- data.tar.gz: 176e92ee884fb86e0ef764bf05478cebb940183b07082f6f8ade8cec1162648cdcc319ace98fdd6776e9f2506afa9f2794163e483a0493445a252f97d9b619e2
6
+ metadata.gz: c4abf169be0eff5474adfa835e34d4035d2278b38ae8f56211b47a611d352f52048df27d75b557b1f4ac61d96ec44b2240eb3e0e4365b4bb32fffc9f577db35d
7
+ data.tar.gz: aabaf695df10333689e85d8499a8ba0066af11c08b40f62a330123db012b03e81de35f7b03f685ba989be8ec0099852dd9dd5a23a57a997e3e1b9263d61f266e
data/README.md CHANGED
@@ -197,13 +197,9 @@ network. You can see the full list of nodes at `/remotes` URL of your node.
197
197
  your CPUs. It is recommended to make this number equal to the
198
198
  number of CPUs available.
199
199
 
200
- * `scores` is ... something not important to you.
200
+ * `pipeline` is ... something not important to you.
201
201
 
202
- * `best` is ... something not important to you.
203
-
204
- * `history` is the amount of scores currently saved on the disc. The
205
- farm keeps them there in case the node gets restarted. It will load
206
- them back and reuse.
202
+ * `best` is the list of scores known to the farm at the moment (with their ages in minutes).
207
203
 
208
204
  `entrance` is the place where all new wallets arive and get merged and pushed
209
205
  further. The health of this point is critical to the entire node. Some
@@ -42,21 +42,18 @@ module Zold
42
42
  @log = log
43
43
  @cache = cache
44
44
  @invoice = invoice
45
- @scores = []
45
+ @pipeline = Queue.new
46
46
  @threads = []
47
- @best = []
48
47
  @mutex = Mutex.new
49
48
  end
50
49
 
51
50
  def best
52
- @mutex.synchronize do
53
- @best.to_a
54
- end
51
+ load
55
52
  end
56
53
 
57
54
  def to_text
58
55
  @threads.map do |t|
59
- "#{t.name}: status=#{t.status}; alive=#{t.alive};\n #{t.backtrace.join("\n ")}"
56
+ "#{t.name}: status=#{t.status}; alive=#{t.alive?};\n #{t.backtrace.join("\n ")}"
60
57
  end.join("\n")
61
58
  end
62
59
 
@@ -65,18 +62,15 @@ module Zold
65
62
  threads: @threads.map do |t|
66
63
  "#{t.name}/#{t.status}/#{t.alive? ? 'A' : 'D'}"
67
64
  end.join(', '),
68
- scores: @scores.size,
69
- best: @best.map(&:value).join(', '),
70
- history: history.count
65
+ pipeline: @pipeline.size,
66
+ best: best.map { |s| "#{s.value}/#{(s.age / 60).round}m" }.join(', ')
71
67
  }
72
68
  end
73
69
 
74
70
  def start(host, port, strength: 8, threads: 8)
75
- @log.debug('Zero-threads farm won\'t score anything!') if threads.zero?
76
- @scores = Queue.new
77
- @best = history
78
- clean(host, port, strength, threads)
79
- @log.info("#{@scores.size} scores pre-loaded, the best is: #{@best[0]}")
71
+ @log.info('Zero-threads farm won\'t score anything!') if threads.zero?
72
+ cleanup(host, port, strength, threads)
73
+ @log.info("#{@pipeline.size} scores pre-loaded, the best is: #{best[0]}")
80
74
  @threads = (1..threads).map do |t|
81
75
  Thread.new do
82
76
  Thread.current.name = "f#{t}"
@@ -88,11 +82,11 @@ module Zold
88
82
  end
89
83
  end
90
84
  @threads << Thread.new do
91
- Thread.current.name = 'cleaner'
85
+ Thread.current.name = 'cleanup'
92
86
  loop do
93
87
  sleep(60) unless strength == 1 # which will only happen in tests
94
88
  VerboseThread.new(@log).run do
95
- clean(host, port, strength, threads)
89
+ cleanup(host, port, strength, threads)
96
90
  end
97
91
  end
98
92
  end
@@ -118,49 +112,56 @@ module Zold
118
112
 
119
113
  private
120
114
 
121
- def clean(host, port, strength, threads)
122
- @mutex.synchronize do
123
- before = @best.map(&:value).max.to_i
124
- @best = @best.select(&:valid?).reject(&:expired?).sort_by(&:value).reverse
125
- @best = @best.take(threads) unless threads.zero?
126
- if @best.empty? || !threads.zero? && @best.map(&:age_hours).min > 24 / threads
127
- @best << Score.new(Time.now, host, port, @invoice, strength: strength)
128
- end
129
- @best.sort_by(&:age_hours).each { |b| @scores << b }
130
- after = @best.map(&:value).max
131
- @log.debug("#{Thread.current.name}: best score is #{@best[0]}") if before != after && !after.zero?
115
+ def cleanup(host, port, strength, threads)
116
+ scores = load
117
+ before = scores.map(&:value).max.to_i
118
+ if scores.empty? || !threads.zero? && scores.map(&:age).min > 24 * 60 * 60 / threads
119
+ save([Score.new(Time.now, host, port, @invoice, strength: strength)])
120
+ else
121
+ save
132
122
  end
123
+ scores = load
124
+ @pipeline << scores.min_by(&:age) if @pipeline.size < threads
125
+ after = scores.map(&:value).max.to_i
126
+ @log.debug("#{Thread.current.name}: best score is #{scores[0]}") if before != after && !after.zero?
133
127
  end
134
128
 
135
129
  def cycle(host, port, strength, threads)
136
- s = @scores.pop
130
+ s = @pipeline.pop
137
131
  return unless s.valid?
138
132
  return unless s.host == host
139
133
  return unless s.port == port
140
134
  return unless s.strength >= strength
141
- n = s.next
142
- @mutex.synchronize do
143
- save(n)
144
- @best << n
145
- end
146
- clean(host, port, strength, threads)
147
- @scores << n
135
+ save([s.next])
136
+ cleanup(host, port, strength, threads)
148
137
  end
149
138
 
150
- def save(score)
151
- AtomicFile.new(@cache).write((history + [score]).map(&:to_s).uniq.join("\n"))
139
+ def save(list = [])
140
+ scores = load + list
141
+ @mutex.synchronize do
142
+ AtomicFile.new(@cache).write(
143
+ scores.select(&:valid?)
144
+ .reject(&:expired?)
145
+ .map(&:to_s)
146
+ .uniq
147
+ .join("\n")
148
+ )
149
+ end
152
150
  end
153
151
 
154
- def history
155
- if File.exist?(@cache)
156
- AtomicFile.new(@cache).read
157
- .split(/\n/)
158
- .map { |t| Score.parse(t) }
159
- .select(&:valid?)
160
- .sort_by(&:value)
161
- .reverse
162
- else
163
- []
152
+ def load
153
+ @mutex.synchronize do
154
+ if File.exist?(@cache)
155
+ AtomicFile.new(@cache).read
156
+ .split(/\n/)
157
+ .map { |t| Score.parse(t) }
158
+ .select(&:valid?)
159
+ .reject(&:expired?)
160
+ .sort_by(&:value)
161
+ .reverse
162
+ else
163
+ []
164
+ end
164
165
  end
165
166
  end
166
167
  end
data/lib/zold/score.rb CHANGED
@@ -141,7 +141,7 @@ module Zold
141
141
  hash: value.zero? ? nil : hash,
142
142
  expired: expired?,
143
143
  valid: valid?,
144
- minutes: ((Time.now - @time) / 60).to_i,
144
+ age: (age / 60).round,
145
145
  created: @created.utc.iso8601
146
146
  }
147
147
  end
@@ -168,12 +168,12 @@ module Zold
168
168
  end
169
169
  end
170
170
 
171
- def age_hours
172
- (Time.now - @time) / (60 * 60)
171
+ def age
172
+ Time.now - @time
173
173
  end
174
174
 
175
175
  def expired?(hours = 24)
176
- age_hours > hours
176
+ age > hours * 60 * 60
177
177
  end
178
178
 
179
179
  def prefix
data/lib/zold/version.rb CHANGED
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Zold
26
- VERSION = '0.13.22'.freeze
26
+ VERSION = '0.13.23'.freeze
27
27
  end
@@ -32,12 +32,21 @@ class FarmTest < Minitest::Test
32
32
  farm.start('localhost', 80, threads: 4, strength: 2) do
33
33
  sleep 0.1 while farm.best.empty? || farm.best[0].value.zero?
34
34
  count = 0
35
- 100.times { count += farm.to_json[:history] }
35
+ 100.times { count += farm.to_json[:best].length }
36
36
  assert(count > 0)
37
37
  end
38
38
  end
39
39
  end
40
40
 
41
+ def test_renders_in_text
42
+ Dir.mktmpdir 'test' do |dir|
43
+ farm = Zold::Farm.new('NOPREFIX@ffffffffffffffff', File.join(dir, 'f'), log: test_log)
44
+ farm.start('localhost', 80, threads: 2, strength: 1) do
45
+ assert(!farm.to_text.nil?)
46
+ end
47
+ end
48
+ end
49
+
41
50
  def test_makes_best_score_in_background
42
51
  Dir.mktmpdir 'test' do |dir|
43
52
  farm = Zold::Farm.new('NOPREFIX@ffffffffffffffff', File.join(dir, 'f'), log: test_log)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.22
4
+ version: 0.13.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-15 00:00:00.000000000 Z
11
+ date: 2018-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby