zold 0.17.6 → 0.17.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7a2934cd243231fd712085b3f87a94d6bb4bf614cc1f5a1e9cada9f7268939d
4
- data.tar.gz: f92eb91031505dee84d3bdbbc072e3d7384494e4954a5420b7656b8089d425e7
3
+ metadata.gz: 1fe6c89e0f94aab5d15fc27cbd8cd8b25ae870341eb056e442a568430c97b1fa
4
+ data.tar.gz: 55b3c18e4f6c223c521265b4ae1c7cb9c46b5e915df6dbe47f3c176ec0ad00d0
5
5
  SHA512:
6
- metadata.gz: 7d974ce11c5bf502b56ce917c19ac1d388d3a28399ddcf84e0fc3860dd2935576965451f26750bcf52744c9b33f411a7e885d6c84cdcdcfbecc1699e008d7e5f
7
- data.tar.gz: 7bb56302734385c3a20a824b0c9d312ed5d88b02adca2c6c0d9c68554e91d598f26ed29f2019e0435d4622308c5b0e889cade6737773ace52c62701b4fc2570c
6
+ metadata.gz: 66998849bf25873d1814fee29109744bffddc9c19f39c179388a605b55f6414ec6bb9df72455c3e83439c85475268d752731cf74f574c5aab6e1fdf3505d0aa3
7
+ data.tar.gz: ecd1a71750d26762749ab24c931307713f7b8586ba09d865e324b209d441d3740ddb65df97c59d3409b19b88e22c6a8698881ccbe7d203c2ac9e91563f262edb
@@ -159,9 +159,9 @@ module Zold
159
159
  default: false
160
160
  o.string '--alias',
161
161
  'The alias of the node (default: host:port)'
162
- o.boolean '--no-spawn',
163
- 'Don\'t use child processes for the score farm',
164
- default: false
162
+ o.string '--farmer',
163
+ 'The name of the farmer, e.g. "plain", "spawn", "fork" (default: "plain")',
164
+ default: 'plain'
165
165
  o.bool '--help', 'Print instructions'
166
166
  end
167
167
  if opts.help?
@@ -276,11 +276,19 @@ module Zold
276
276
  private
277
277
 
278
278
  def farmer(opts)
279
- if opts['no-spawn']
280
- @log.debug('Plain farmer is used, only one CPU will be utilized')
281
- return Farmers::Plain.new
279
+ case opts['farmer'].downcase.strip
280
+ when 'plain'
281
+ @log.debug('"Plain" farmer is used, only one CPU will be utilized')
282
+ Farmers::Plain.new
283
+ when 'fork'
284
+ @log.debug('"Fork" farmer is used')
285
+ Farmers::Fork.new(log: @log)
286
+ when 'spawn'
287
+ @log.debug('"Spawn" farmer is used')
288
+ Farmers::Spawn.new(log: @log)
289
+ else
290
+ raise "Farmer name is not recognized: #{opts['farmer']}"
282
291
  end
283
- Farmers::Fork.new(log: @log)
284
292
  end
285
293
 
286
294
  # Returns exit code
@@ -77,5 +77,64 @@ for #{after.host}:#{after.port} in #{Age.new(start)}: #{after.suffixes}")
77
77
  after
78
78
  end
79
79
  end
80
+
81
+ # In a child process
82
+ class Spawn
83
+ def initialize(log: Log::NULL)
84
+ @log = log
85
+ end
86
+
87
+ def up(score)
88
+ start = Time.now
89
+ bin = File.expand_path(File.join(File.dirname(__FILE__), '../../../bin/zold'))
90
+ raise "Zold binary not found at #{bin}" unless File.exist?(bin)
91
+ cmd = [
92
+ 'ruby',
93
+ Shellwords.escape(bin),
94
+ '--skip-upgrades',
95
+ "--info-tid=#{Thread.current.thread_variable_get(:tid)}",
96
+ "--info-thread=#{Shellwords.escape(Thread.current.name)}",
97
+ "--info-start=#{Time.now.utc.iso8601}",
98
+ '--low-priority',
99
+ 'next',
100
+ Shellwords.escape(score)
101
+ ].join(' ')
102
+ Open3.popen2e(cmd) do |stdin, stdout, thr|
103
+ Thread.current.thread_variable_set(:pid, thr.pid.to_s)
104
+ at_exit { Farmers.kill(@log, thr.pid, start) }
105
+ @log.debug("Scoring started in proc ##{thr.pid} \
106
+ for #{score.value}/#{score.strength} at #{score.host}:#{score.port}")
107
+ begin
108
+ stdin.close
109
+ buffer = +''
110
+ loop do
111
+ begin
112
+ buffer << stdout.read_nonblock(16 * 1024)
113
+ # rubocop:disable Lint/HandleExceptions
114
+ rescue IO::WaitReadable => _
115
+ # rubocop:enable Lint/HandleExceptions
116
+ # nothing to do here
117
+ rescue StandardError => e
118
+ @log.error(buffer)
119
+ raise e
120
+ end
121
+ break if buffer.end_with?("\n") && thr.value.to_i.zero?
122
+ if stdout.closed?
123
+ raise "Failed to calculate the score (##{thr.value}): #{buffer}" unless thr.value.to_i.zero?
124
+ break
125
+ end
126
+ sleep(1)
127
+ Thread.current.thread_variable_set(:buffer, buffer.length.to_s)
128
+ end
129
+ after = Score.parse(buffer.strip)
130
+ @log.debug("Next score #{after.value}/#{after.strength} found in proc ##{thr.pid} \
131
+ for #{after.host}:#{after.port} in #{Age.new(start)}: #{after.suffixes}")
132
+ after
133
+ ensure
134
+ Farmers.kill(@log, thr.pid, start)
135
+ end
136
+ end
137
+ end
138
+ end
80
139
  end
81
140
  end
@@ -104,21 +104,21 @@ module Zold
104
104
 
105
105
  def assert_valid_score(score)
106
106
  raise "Invalid score #{score}" unless score.valid?
107
- raise "Expired score (#{Age.new(score.time)}) #{score.reduce(4)}" if score.expired?
107
+ raise "Expired score (#{Age.new(score.time)}) #{score.reduced(4)}" if score.expired?
108
108
  end
109
109
 
110
110
  def assert_score_ownership(score)
111
- raise "Masqueraded host #{@host} as #{score.host}: #{score.reduce(4)}" if @host != score.host
112
- raise "Masqueraded port #{@port} as #{score.port}: #{score.reduce(4)}" if @port != score.port
111
+ raise "Masqueraded host #{@host} as #{score.host}: #{score.reduced(4)}" if @host != score.host
112
+ raise "Masqueraded port #{@port} as #{score.port}: #{score.reduced(4)}" if @port != score.port
113
113
  end
114
114
 
115
115
  def assert_score_strength(score)
116
116
  return if score.strength >= Score::STRENGTH
117
- raise "Score #{score.strength} is too weak (<#{Score::STRENGTH}): #{score.reduce(4)}"
117
+ raise "Score #{score.strength} is too weak (<#{Score::STRENGTH}): #{score.reduced(4)}"
118
118
  end
119
119
 
120
120
  def assert_score_value(score, min)
121
- raise "Score #{score.value} is too small (<#{min}): #{score.reduce(4)}" if score.value < min
121
+ raise "Score #{score.value} is too small (<#{min}): #{score.reduced(4)}" if score.value < min
122
122
  end
123
123
  end
124
124
 
@@ -25,6 +25,6 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.17.6'
28
+ VERSION = '0.17.7'
29
29
  PROTOCOL = 2
30
30
  end
@@ -28,9 +28,16 @@ require_relative '../../lib/zold/node/farmers'
28
28
  require_relative '../../lib/zold/verbose_thread'
29
29
 
30
30
  class FarmersTest < Zold::Test
31
+ # Types to test
32
+ TYPES = [
33
+ Zold::Farmers::Plain,
34
+ Zold::Farmers::Spawn,
35
+ Zold::Farmers::Fork
36
+ ].freeze
37
+
31
38
  def test_calculates_next_score
32
39
  before = Zold::Score.new(host: 'some-host', port: 9999, invoice: 'NOPREFIX4@ffffffffffffffff', strength: 3)
33
- [Zold::Farmers::Plain, Zold::Farmers::Fork].each do |farmer_class|
40
+ TYPES.each do |farmer_class|
34
41
  farmer = farmer_class.new(log: test_log)
35
42
  after = farmer.up(before)
36
43
  assert_equal(1, after.value)
@@ -41,7 +48,7 @@ class FarmersTest < Zold::Test
41
48
  end
42
49
 
43
50
  def test_calculates_large_score
44
- [Zold::Farmers::Plain, Zold::Farmers::Fork].each do |type|
51
+ TYPES.each do |type|
45
52
  log = TestLogger.new(test_log)
46
53
  thread = Thread.start do
47
54
  farmer = type.new(log: log)
@@ -54,7 +61,7 @@ class FarmersTest < Zold::Test
54
61
  end
55
62
 
56
63
  def test_kills_farmer
57
- [Zold::Farmers::Plain, Zold::Farmers::Fork].each do |type|
64
+ TYPES.each do |type|
58
65
  farmer = type.new(log: test_log)
59
66
  thread = Thread.start do
60
67
  Zold::VerboseThread.new(test_log).run do
@@ -283,7 +283,7 @@ class FrontTest < Zold::Test
283
283
  # HTTP request. This value is enough to identify a valueable node, and filter
284
284
  # out those that are too weak.
285
285
  def test_score_is_reduced
286
- FakeNode.new(log: test_log).run(['--threads=1', '--strength=1', '--no-metronome', '--no-spawn']) do |port|
286
+ FakeNode.new(log: test_log).run(['--threads=1', '--strength=1', '--no-metronome', '--farmer=plain']) do |port|
287
287
  res = Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
288
288
  assert_wait { Zold::Score.parse(res.headers[Zold::Http::SCORE_HEADER]).value > Zold::Front::MIN_SCORE - 1 }
289
289
  sleep(1)
@@ -65,7 +65,7 @@ and suggests a different architecture for digital wallet maintenance.'
65
65
  s.add_runtime_dependency 'concurrent-ruby', '1.1.3'
66
66
  s.add_runtime_dependency 'cucumber', '3.1.2' # has to stay here for Heroku
67
67
  s.add_runtime_dependency 'diffy', '3.2.1'
68
- s.add_runtime_dependency 'futex', '0.6.1'
68
+ s.add_runtime_dependency 'futex', '0.6.2'
69
69
  s.add_runtime_dependency 'get_process_mem', '0.2.3'
70
70
  s.add_runtime_dependency 'json', '2.1.0'
71
71
  s.add_runtime_dependency 'memory_profiler', '0.9.12'
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.17.6
4
+ version: 0.17.7
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-12-03 00:00:00.000000000 Z
11
+ date: 2018-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.1
75
+ version: 0.6.2
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.1
82
+ version: 0.6.2
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: get_process_mem
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -700,7 +700,7 @@ licenses:
700
700
  - MIT
701
701
  metadata: {}
702
702
  post_install_message: |-
703
- Thanks for installing Zold 0.17.6!
703
+ Thanks for installing Zold 0.17.7!
704
704
  Study our White Paper: https://papers.zold.io/wp.pdf
705
705
  Read our blog posts: https://blog.zold.io
706
706
  Try online wallet at: https://wts.zold.io