zold 0.20.1 → 0.20.2
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 +4 -4
- data/bin/zold +23 -7
- data/fixtures/merge/into-no-wallet/copies/0123456789abcdef/scores.zc +1 -1
- data/fixtures/merge/random-expenses/copies/0123456789abcdef/scores.zc +5 -5
- data/fixtures/merge/simple-case/copies/0123456789abcdef/scores.zc +1 -1
- data/lib/zold/age.rb +2 -1
- data/lib/zold/amount.rb +3 -0
- data/lib/zold/cached_wallets.rb +2 -2
- data/lib/zold/commands/calculate.rb +1 -1
- data/lib/zold/commands/clean.rb +6 -1
- data/lib/zold/commands/fetch.rb +5 -4
- data/lib/zold/commands/merge.rb +2 -1
- data/lib/zold/commands/node.rb +46 -10
- data/lib/zold/commands/push.rb +4 -2
- data/lib/zold/commands/routines/audit.rb +53 -0
- data/lib/zold/commands/routines/gc.rb +1 -1
- data/lib/zold/copies.rb +15 -8
- data/lib/zold/head.rb +15 -14
- data/lib/zold/hungry_wallets.rb +2 -2
- data/lib/zold/id.rb +4 -8
- data/lib/zold/metronome.rb +4 -4
- data/lib/zold/node/async_entrance.rb +7 -3
- data/lib/zold/node/farm.rb +1 -1
- data/lib/zold/node/front.rb +8 -5
- data/lib/zold/node/sync_entrance.rb +4 -0
- data/lib/zold/remotes.rb +57 -55
- data/lib/zold/tax.rb +2 -2
- data/lib/zold/thread_pool.rb +18 -14
- data/lib/zold/tree_wallets.rb +1 -1
- data/lib/zold/txn.rb +32 -3
- data/lib/zold/txns.rb +14 -14
- data/lib/zold/verbose_thread.rb +7 -0
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallet.rb +2 -2
- data/test/commands/routines/test_audit.rb +41 -0
- data/test/commands/test_clean.rb +3 -3
- data/test/node/fake_node.rb +2 -1
- data/test/node/test_async_entrance.rb +3 -1
- data/test/node/test_front.rb +1 -0
- data/test/node/test_sync_entrance.rb +2 -2
- data/test/test_copies.rb +14 -5
- data/test/test_tree_wallets.rb +17 -7
- data/test/test_txn.rb +8 -0
- data/test/test_wallet.rb +17 -0
- data/zold.gemspec +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d066e22fce978f4fdee5ebf56c935c3f05a09a1c7ad57c6da8ed6388db63eb84
|
4
|
+
data.tar.gz: e505ab03aafc00413ba0f71513fb4bd0f5e06794da6704a2ea335275285222cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4313b16d11fb3226c35a0db9b3e7367b9550b008c2be560c3281ae05c8bae9f5249f53b5a7fbd8cd429f3f8207db098e6dada0ed3af68cb1bff927a1f45ce804
|
7
|
+
data.tar.gz: e2a483f2eff040a1429e96c0a515a00c8a7566ab200ed23ab18b6d6d5dc89c6fecda4d107ef0c21f3481df4759cf0ae6f70ca0c94b5f9270f798ee211854f737
|
data/bin/zold
CHANGED
@@ -29,9 +29,11 @@ require 'slop'
|
|
29
29
|
require 'rainbow'
|
30
30
|
require 'backtrace'
|
31
31
|
require 'memory_profiler'
|
32
|
+
require 'get_process_mem'
|
32
33
|
require_relative '../lib/zold'
|
33
34
|
require_relative '../lib/zold/version'
|
34
35
|
require_relative '../lib/zold/wallet'
|
36
|
+
require_relative '../lib/zold/dir_items'
|
35
37
|
require_relative '../lib/zold/wallets'
|
36
38
|
require_relative '../lib/zold/tree_wallets'
|
37
39
|
require_relative '../lib/zold/sync_wallets'
|
@@ -40,6 +42,7 @@ require_relative '../lib/zold/hungry_wallets'
|
|
40
42
|
require_relative '../lib/zold/log'
|
41
43
|
require_relative '../lib/zold/key'
|
42
44
|
require_relative '../lib/zold/age'
|
45
|
+
require_relative '../lib/zold/size'
|
43
46
|
require_relative '../lib/zold/amount'
|
44
47
|
require_relative '../lib/zold/copies'
|
45
48
|
require_relative '../lib/zold/remotes'
|
@@ -159,20 +162,27 @@ FileUtils.mkdir_p(home)
|
|
159
162
|
Dir.chdir(home)
|
160
163
|
log.debug("Home directory: #{home}")
|
161
164
|
|
162
|
-
|
165
|
+
zdata = File.join(home, '.zoldata')
|
163
166
|
|
164
167
|
unless opts['skip-upgrades']
|
165
|
-
Zold::Upgrades.new(Zold::VersionFile.new(File.join(
|
168
|
+
Zold::Upgrades.new(Zold::VersionFile.new(File.join(zdata, 'version')), 'upgrades', { command: command, network: opts['network']}).run
|
166
169
|
end
|
167
170
|
|
171
|
+
locks = File.join(zdata, 'locks')
|
172
|
+
Zold::DirItems.new(locks).fetch.each do |f|
|
173
|
+
file = File.join(locks, f)
|
174
|
+
if File.mtime(file) < Time.now - 60
|
175
|
+
File.delete(file)
|
176
|
+
end
|
177
|
+
end
|
168
178
|
wallets = Zold::SyncWallets.new(
|
169
179
|
Zold::CachedWallets.new(
|
170
180
|
command == 'node' ? Zold::TreeWallets.new(home) : Zold::Wallets.new(home)
|
171
181
|
),
|
172
182
|
log: log,
|
173
|
-
dir:
|
183
|
+
dir: locks
|
174
184
|
)
|
175
|
-
fremotes = File.join(
|
185
|
+
fremotes = File.join(zdata, 'remotes')
|
176
186
|
remotes = Zold::Remotes.new(file: fremotes, network: opts['network'])
|
177
187
|
if File.exist?(fremotes)
|
178
188
|
log.debug("Remote nodes: #{remotes.all.count} total")
|
@@ -180,9 +190,10 @@ else
|
|
180
190
|
remotes.masters
|
181
191
|
log.debug("Default remotes have been set: #{remotes.all.count} total")
|
182
192
|
end
|
183
|
-
copies = File.join(
|
193
|
+
copies = File.join(zdata, 'copies')
|
184
194
|
|
185
195
|
log.debug("Network: #{opts['network']} (#{opts['network'] == Zold::Wallet::MAINET ? 'main' : 'test'} net)")
|
196
|
+
log.debug("Memory footprint at start is #{Zold::Size.new(GetProcessMem.new.bytes.to_i)}")
|
186
197
|
|
187
198
|
cmd = lambda do
|
188
199
|
begin
|
@@ -262,6 +273,11 @@ else
|
|
262
273
|
code = cmd.call
|
263
274
|
end
|
264
275
|
|
265
|
-
|
276
|
+
log.debug("Memory footprint at the end is #{Zold::Size.new(GetProcessMem.new.bytes.to_i)}")
|
277
|
+
if code.zero?
|
278
|
+
log.debug("Failed in in #{Zold::Age.new(start)}")
|
279
|
+
exit(code)
|
280
|
+
else
|
281
|
+
log.debug("Successfully finished in #{Zold::Age.new(start)}")
|
282
|
+
end
|
266
283
|
|
267
|
-
log.debug("Successfully finished in #{Zold::Age.new(start)}")
|
@@ -1 +1 @@
|
|
1
|
-
1,0.0.0.0,4096,50,NOW
|
1
|
+
1,0.0.0.0,4096,50,NOW,M
|
@@ -1,5 +1,5 @@
|
|
1
|
-
1,0.0.0.0,4096,10,NOW
|
2
|
-
2,0.0.0.0,4096,20,NOW
|
3
|
-
3,0.0.0.0,4096,30,NOW
|
4
|
-
4,0.0.0.0,4096,40,NOW
|
5
|
-
5,0.0.0.0,4096,50,NOW
|
1
|
+
1,0.0.0.0,4096,10,NOW,M
|
2
|
+
2,0.0.0.0,4096,20,NOW,E
|
3
|
+
3,0.0.0.0,4096,30,NOW,E
|
4
|
+
4,0.0.0.0,4096,40,NOW,E
|
5
|
+
5,0.0.0.0,4096,50,NOW,E
|
@@ -1 +1 @@
|
|
1
|
-
1,0.0.0.0,4096,50,NOW
|
1
|
+
1,0.0.0.0,4096,50,NOW,M
|
data/lib/zold/age.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'time'
|
24
24
|
require 'rainbow'
|
25
|
+
require_relative 'txn'
|
25
26
|
|
26
27
|
# Age in seconds.
|
27
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -31,7 +32,7 @@ module Zold
|
|
31
32
|
# Age
|
32
33
|
class Age
|
33
34
|
def initialize(time, limit: nil)
|
34
|
-
@time = time.nil? || time.is_a?(Time) ? time :
|
35
|
+
@time = time.nil? || time.is_a?(Time) ? time : Txn.parse_time(time)
|
35
36
|
@limit = limit
|
36
37
|
end
|
37
38
|
|
data/lib/zold/amount.rb
CHANGED
@@ -50,12 +50,15 @@ module Zold
|
|
50
50
|
raise "The amount is too small: #{@zents}" if @zents < -MAX
|
51
51
|
end
|
52
52
|
|
53
|
+
# Just zero, for convenience.
|
53
54
|
ZERO = Amount.new(zents: 0)
|
54
55
|
|
56
|
+
# Convert it to zents and return as an integer.
|
55
57
|
def to_i
|
56
58
|
@zents
|
57
59
|
end
|
58
60
|
|
61
|
+
# Convert to ZLD and return as a string. If you need float, you should use <tt>to_f()</tt> later.
|
59
62
|
def to_zld(digits = 2)
|
60
63
|
format("%0.#{digits}f", @zents.to_f / 2**FRACTION)
|
61
64
|
end
|
data/lib/zold/cached_wallets.rb
CHANGED
@@ -38,7 +38,7 @@ module Zold
|
|
38
38
|
@clean = ThreadPool.new('cached-wallets')
|
39
39
|
@clean.add do
|
40
40
|
Endless.new('cached_wallets').run do
|
41
|
-
sleep
|
41
|
+
sleep 5
|
42
42
|
@zache.clean
|
43
43
|
end
|
44
44
|
end
|
@@ -47,7 +47,7 @@ module Zold
|
|
47
47
|
|
48
48
|
def acq(id, exclusive: false)
|
49
49
|
@wallets.acq(id, exclusive: exclusive) do |wallet|
|
50
|
-
c = @zache.get(id.to_s, lifetime:
|
50
|
+
c = @zache.get(id.to_s, lifetime: 15) { wallet }
|
51
51
|
res = yield c
|
52
52
|
c.flush if exclusive
|
53
53
|
res
|
@@ -79,7 +79,7 @@ Available options:"
|
|
79
79
|
strength = opts[:strength]
|
80
80
|
raise "Invalid strength: #{strength}" if strength <= 0 || strength > 8
|
81
81
|
score = Zold::Score.new(
|
82
|
-
time:
|
82
|
+
time: Txn.parse_time(opts[:time]), host: opts[:host], port: opts[:port].to_i,
|
83
83
|
invoice: opts[:invoice], strength: strength
|
84
84
|
)
|
85
85
|
loop do
|
data/lib/zold/commands/clean.rb
CHANGED
@@ -33,6 +33,7 @@ require_relative '../size'
|
|
33
33
|
require_relative '../log'
|
34
34
|
require_relative '../http'
|
35
35
|
require_relative '../copies'
|
36
|
+
require_relative '../thread_pool'
|
36
37
|
|
37
38
|
# CLEAN command.
|
38
39
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -51,10 +52,14 @@ module Zold
|
|
51
52
|
opts = Slop.parse(args, help: true, suppress_errors: true) do |o|
|
52
53
|
o.banner = "Usage: zold clean [ID...] [options]
|
53
54
|
Available options:"
|
55
|
+
o.integer '--threads',
|
56
|
+
"How many threads to use for cleaning copies (default: #{[Concurrent.processor_count / 2, 2].max})",
|
57
|
+
default: [Concurrent.processor_count / 2, 2].max
|
54
58
|
o.bool '--help', 'Print instructions'
|
55
59
|
end
|
56
60
|
mine = Args.new(opts, @log).take || return
|
57
|
-
|
61
|
+
list = mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }
|
62
|
+
ThreadPool.new('clean', log: @log).run(opts['threads'], list.uniq) do |id|
|
58
63
|
clean(Copies.new(File.join(@copies, id), log: @log), opts)
|
59
64
|
end
|
60
65
|
end
|
data/lib/zold/commands/fetch.rb
CHANGED
@@ -91,7 +91,7 @@ Available options:"
|
|
91
91
|
end
|
92
92
|
mine = Args.new(opts, @log).take || return
|
93
93
|
list = mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }
|
94
|
-
ThreadPool.new('fetch', log: @log).run(opts['threads'], list) do |id|
|
94
|
+
ThreadPool.new('fetch', log: @log).run(opts['threads'], list.uniq) do |id|
|
95
95
|
fetch(id, Copies.new(File.join(@copies, id)), opts)
|
96
96
|
end
|
97
97
|
end
|
@@ -112,7 +112,9 @@ Available options:"
|
|
112
112
|
done.increment
|
113
113
|
end
|
114
114
|
unless opts['quiet-if-absent']
|
115
|
-
|
115
|
+
if done.value.zero?
|
116
|
+
raise "No nodes out of #{nodes.value} have the wallet #{id}; run 'zold remote update' and try again"
|
117
|
+
end
|
116
118
|
if masters.value.zero? && !opts['tolerate-edges']
|
117
119
|
raise EdgesOnly, "There are only edge nodes, run 'zold remote update' or use --tolerate-edges"
|
118
120
|
end
|
@@ -140,7 +142,6 @@ run 'zold remote update' or use --tolerate-quorum=1"
|
|
140
142
|
size = r.http(uri + '/size').get
|
141
143
|
r.assert_code(200, size)
|
142
144
|
res = r.http(uri).get(timeout: 2 + size.body.to_i * 0.01 / 1024)
|
143
|
-
raise "Wallet #{id} not found" if res.status == '404'
|
144
145
|
r.assert_code(200, res)
|
145
146
|
json = JsonPage.new(res.body, uri).to_hash
|
146
147
|
score = Score.parse_json(json['score'])
|
@@ -161,7 +162,7 @@ run 'zold remote update' or use --tolerate-quorum=1"
|
|
161
162
|
if wallet.balance.negative? && !wallet.root?
|
162
163
|
raise "The balance of #{id} is #{wallet.balance} and it's not a root wallet"
|
163
164
|
end
|
164
|
-
copy = cps.add(IO.read(f), score.host, score.port, score.value)
|
165
|
+
copy = cps.add(IO.read(f), score.host, score.port, score.value, master: r.master?)
|
165
166
|
@log.info("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
|
166
167
|
as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
|
167
168
|
#{Rainbow(score.value).green} (#{json['version']})")
|
data/lib/zold/commands/merge.rb
CHANGED
@@ -72,7 +72,8 @@ Available options:"
|
|
72
72
|
end
|
73
73
|
mine = Args.new(opts, @log).take || return
|
74
74
|
modified = []
|
75
|
-
|
75
|
+
list = mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }
|
76
|
+
list.uniq.each do |id|
|
76
77
|
next unless merge(id, Copies.new(File.join(@copies, id)), opts)
|
77
78
|
modified << id
|
78
79
|
next if opts['skip-propagate']
|
data/lib/zold/commands/node.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
require 'open3'
|
24
24
|
require 'slop'
|
25
25
|
require 'backtrace'
|
26
|
+
require 'fileutils'
|
26
27
|
require 'zache'
|
27
28
|
require 'concurrent'
|
28
29
|
require 'zold/score'
|
@@ -132,6 +133,15 @@ module Zold
|
|
132
133
|
o.bool '--no-cache',
|
133
134
|
'Skip caching of front JSON pages (will seriously slow down, mostly useful for testing)',
|
134
135
|
default: false
|
136
|
+
o.boolean '--skip-audit',
|
137
|
+
'Don\'t report audit information to the console every minute',
|
138
|
+
default: false
|
139
|
+
o.boolean '--skip-reconnect',
|
140
|
+
'Don\'t reconnect to the network every minute (for testing)',
|
141
|
+
default: false
|
142
|
+
o.boolean '--not-hungry',
|
143
|
+
'Don\'t do hugry pulling of missed nodes (mostly for testing)',
|
144
|
+
default: false
|
135
145
|
o.bool '--allow-spam',
|
136
146
|
'Don\'t filter the incoming spam via PUT requests (duplicate wallets)',
|
137
147
|
default: false
|
@@ -139,11 +149,14 @@ module Zold
|
|
139
149
|
'Skip Out Of Memory check and never exit, no matter how much RAM is consumed',
|
140
150
|
default: false
|
141
151
|
o.integer '--oom-limit',
|
142
|
-
'Maximum amount of memory we can consume, quit if we take more than that, in Mb (default:
|
143
|
-
default:
|
152
|
+
'Maximum amount of memory we can consume, quit if we take more than that, in Mb (default: 512)',
|
153
|
+
default: 512
|
144
154
|
o.integer '--queue-limit',
|
145
155
|
'The maximum number of wallets to be accepted via PUSH and stored in the queue (default: 256)',
|
146
156
|
default: 256
|
157
|
+
o.bool '--skip-gc',
|
158
|
+
'Don\'t run garbage collector and never remove any wallets from the disk',
|
159
|
+
default: false
|
147
160
|
o.integer '--gc-age',
|
148
161
|
'Maximum time in seconds to keep an empty and unused wallet on the disk',
|
149
162
|
default: 60 * 60 * 24 * 10
|
@@ -221,8 +234,17 @@ module Zold
|
|
221
234
|
Zold::Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s])
|
222
235
|
@log.info("Removed current node (#{address}) from list of remotes")
|
223
236
|
end
|
224
|
-
|
225
|
-
|
237
|
+
if File.exist?(@copies)
|
238
|
+
FileUtils.rm_rf(@copies)
|
239
|
+
@log.info("Directory #{@copies} deleted")
|
240
|
+
end
|
241
|
+
wts = @wallets
|
242
|
+
if opts['not-hungry']
|
243
|
+
@log.info('Hungry pulling disabled because of --not-hungry')
|
244
|
+
else
|
245
|
+
hungry = Zold::ThreadPool.new('hungry', log: @log)
|
246
|
+
wts = Zold::HungryWallets.new(@wallets, @remotes, @copies, hungry, log: @log, network: opts['network'])
|
247
|
+
end
|
226
248
|
Front.set(:zache, Zache.new(dirty: true))
|
227
249
|
Front.set(:wallets, wts)
|
228
250
|
Front.set(:remotes, @remotes)
|
@@ -279,7 +301,7 @@ module Zold
|
|
279
301
|
end
|
280
302
|
end
|
281
303
|
end
|
282
|
-
hungry.kill
|
304
|
+
hungry.kill unless opts['not-hungry']
|
283
305
|
@log.info('Thanks for helping Zold network!')
|
284
306
|
end
|
285
307
|
|
@@ -383,14 +405,28 @@ module Zold
|
|
383
405
|
def metronome(farm, opts)
|
384
406
|
metronome = Metronome.new(@log)
|
385
407
|
if opts['no-metronome']
|
386
|
-
@log.info(
|
408
|
+
@log.info("Metronome hasn't been started because of --no-metronome")
|
387
409
|
return metronome
|
388
410
|
end
|
389
|
-
|
390
|
-
|
411
|
+
if opts['skip-gc']
|
412
|
+
@log.info('Garbage collection is disabled because of --skip-gc')
|
413
|
+
else
|
414
|
+
require_relative 'routines/gc'
|
415
|
+
metronome.add(Routines::Gc.new(opts, @wallets, log: @log))
|
416
|
+
end
|
417
|
+
if opts['skip-audit']
|
418
|
+
@log.info('Audit is disabled because of --skip-audit')
|
419
|
+
else
|
420
|
+
require_relative 'routines/audit'
|
421
|
+
metronome.add(Routines::Audit.new(opts, @wallets, log: @log))
|
422
|
+
end
|
391
423
|
unless opts['standalone']
|
392
|
-
|
393
|
-
|
424
|
+
if opts['skip-reconnect']
|
425
|
+
@log.info('Reconnect is disabled because of --skip-reconnect')
|
426
|
+
else
|
427
|
+
require_relative 'routines/reconnect'
|
428
|
+
metronome.add(Routines::Reconnect.new(opts, @remotes, farm, network: opts['network'], log: @log))
|
429
|
+
end
|
394
430
|
end
|
395
431
|
@log.info('Metronome started (use --no-metronome to disable it)')
|
396
432
|
metronome
|
data/lib/zold/commands/push.rb
CHANGED
@@ -83,7 +83,7 @@ Available options:"
|
|
83
83
|
end
|
84
84
|
mine = Args.new(opts, @log).take || return
|
85
85
|
list = mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }
|
86
|
-
ThreadPool.new('push', log: @log).run(opts['threads'], list) do |id|
|
86
|
+
ThreadPool.new('push', log: @log).run(opts['threads'], list.uniq) do |id|
|
87
87
|
push(id, opts)
|
88
88
|
end
|
89
89
|
end
|
@@ -104,7 +104,9 @@ Available options:"
|
|
104
104
|
done.increment
|
105
105
|
end
|
106
106
|
unless opts['quiet-if-missed']
|
107
|
-
|
107
|
+
if done.value.zero?
|
108
|
+
raise "No nodes out of #{nodes} accepted the wallet #{id}; run 'zold remote update' and try again"
|
109
|
+
end
|
108
110
|
if masters.value.zero? && !opts['tolerate-edges']
|
109
111
|
raise EdgesOnly, "There are only edge nodes, run 'zold remote update' or use --tolerate-edges"
|
110
112
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'get_process_mem'
|
24
|
+
require_relative '../../size'
|
25
|
+
|
26
|
+
# Audit and report as much as we can to the command line.
|
27
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
29
|
+
# License:: MIT
|
30
|
+
module Zold
|
31
|
+
# Routines module
|
32
|
+
module Routines
|
33
|
+
# Audit the system
|
34
|
+
class Audit
|
35
|
+
def initialize(opts, wallets, log: Log::NULL)
|
36
|
+
@opts = opts
|
37
|
+
@wallets = wallets
|
38
|
+
@log = log
|
39
|
+
end
|
40
|
+
|
41
|
+
def exec(_ = 0)
|
42
|
+
sleep(60) unless @opts['routine-immediately']
|
43
|
+
@log.info(
|
44
|
+
'Audit: ' + [
|
45
|
+
"memory used: #{Size.new(GetProcessMem.new.bytes.to_i)}",
|
46
|
+
"threads total: #{Thread.list.count}",
|
47
|
+
"wallets: #{@wallets.count}"
|
48
|
+
].join('; ')
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -47,7 +47,7 @@ module Zold
|
|
47
47
|
removed = 0
|
48
48
|
@wallets.all.each do |id|
|
49
49
|
seen += 1
|
50
|
-
next unless @wallets.acq(id) { |w| w.exists? && w.
|
50
|
+
next unless @wallets.acq(id) { |w| w.exists? && w.mtime < Time.now - @opts['gc-age'] && w.txns.empty? }
|
51
51
|
cmd.run(args + [id.to_s])
|
52
52
|
removed += 1
|
53
53
|
end
|
data/lib/zold/copies.rb
CHANGED
@@ -89,7 +89,7 @@ module Zold
|
|
89
89
|
end
|
90
90
|
|
91
91
|
# Returns the name of the copy
|
92
|
-
def add(content, host, port, score, time
|
92
|
+
def add(content, host, port, score, time: Time.now, master: false)
|
93
93
|
raise "Content can't be empty" if content.empty?
|
94
94
|
raise 'TCP port must be of type Integer' unless port.is_a?(Integer)
|
95
95
|
raise "TCP port can't be negative: #{port}" if port.negative?
|
@@ -121,7 +121,8 @@ module Zold
|
|
121
121
|
host: host,
|
122
122
|
port: port,
|
123
123
|
score: score,
|
124
|
-
time: time
|
124
|
+
time: time,
|
125
|
+
master: master
|
125
126
|
}
|
126
127
|
save(list)
|
127
128
|
name
|
@@ -134,24 +135,27 @@ module Zold
|
|
134
135
|
{
|
135
136
|
name: name,
|
136
137
|
path: File.join(@dir, "#{name}#{Copies::EXT}"),
|
138
|
+
total: scores.count,
|
139
|
+
master: scores.any? { |s| s[:master] },
|
137
140
|
score: scores.select { |s| s[:time] > Time.now - 24 * 60 * 60 }
|
138
141
|
.map { |s| s[:score] }
|
139
142
|
.inject(&:+) || 0
|
140
143
|
}
|
141
|
-
end.select { |c| File.exist?(c[:path]) }.sort_by { |c| c[:score] }.reverse
|
144
|
+
end.select { |c| File.exist?(c[:path]) }.sort_by { |c| [c[:master] ? 1 : 0, c[:score].to_s] }.reverse
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
145
148
|
def load
|
146
149
|
FileUtils.mkdir_p(File.dirname(file))
|
147
150
|
FileUtils.touch(file)
|
148
|
-
CSV.read(file).map do |s|
|
151
|
+
CSV.read(file).select { |s| s.count == 6 }.map do |s|
|
149
152
|
{
|
150
153
|
name: s[0],
|
151
154
|
host: s[1],
|
152
155
|
port: s[2].to_i,
|
153
156
|
score: s[3].to_i,
|
154
|
-
time:
|
157
|
+
time: Txn.parse_time(s[4]),
|
158
|
+
master: s[5] == 'M'
|
155
159
|
}
|
156
160
|
end
|
157
161
|
end
|
@@ -163,9 +167,12 @@ module Zold
|
|
163
167
|
file,
|
164
168
|
list.map do |r|
|
165
169
|
[
|
166
|
-
r[:name],
|
167
|
-
r[:
|
168
|
-
r[:
|
170
|
+
r[:name],
|
171
|
+
r[:host],
|
172
|
+
r[:port],
|
173
|
+
r[:score],
|
174
|
+
r[:time].utc.iso8601,
|
175
|
+
r[:master] ? 'M' : 'E'
|
169
176
|
].join(',')
|
170
177
|
end.join("\n")
|
171
178
|
)
|