zold 0.11.7 → 0.11.8
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/lib/zold/commands/diff.rb +2 -1
- data/lib/zold/commands/node.rb +2 -3
- data/lib/zold/commands/push.rb +2 -1
- data/lib/zold/commands/remote.rb +1 -1
- data/lib/zold/copies.rb +1 -1
- data/lib/zold/key.rb +2 -1
- data/lib/zold/node/entrance.rb +38 -3
- data/lib/zold/node/farm.rb +2 -1
- data/lib/zold/node/front.rb +5 -3
- data/lib/zold/patch.rb +3 -2
- data/lib/zold/remotes.rb +13 -1
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallet.rb +1 -1
- data/test/node/test_entrance.rb +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73c4792176a13df605a885ea46e4cb92b0df76c6
|
4
|
+
data.tar.gz: 6ca3f32b2975db9dcf533aeb746e80e775224427
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6982d8437738d658d3d530c69525a501cc409237d2ae42c8affe8edc046636e83e06ae1cb51d0fbe8cefa0da9ae30e1a2da43a72c19037b721c631cb765fee73
|
7
|
+
data.tar.gz: 14a0e10962910847fea075ea48b26063e2baac9ed91e1b46453cee53764ebbc641b773bb0de5d8aeb854881852941bad46a15e208e379b5f266017da98d8ce33
|
data/lib/zold/commands/diff.rb
CHANGED
@@ -26,6 +26,7 @@ require_relative 'args'
|
|
26
26
|
require_relative '../log'
|
27
27
|
require_relative '../patch'
|
28
28
|
require_relative '../wallet'
|
29
|
+
require_relative '../atomic_file'
|
29
30
|
|
30
31
|
# DIFF command.
|
31
32
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -69,7 +70,7 @@ Available options:"
|
|
69
70
|
cps[1..-1].each do |c|
|
70
71
|
patch.join(Wallet.new(c[:path]))
|
71
72
|
end
|
72
|
-
before =
|
73
|
+
before = AtomicFile.new(wallet.path).read
|
73
74
|
after = ''
|
74
75
|
Tempfile.open do |f|
|
75
76
|
patch.save(f, overwrite: true)
|
data/lib/zold/commands/node.rb
CHANGED
@@ -98,9 +98,8 @@ module Zold
|
|
98
98
|
Front.set(:copies, copies)
|
99
99
|
address = "#{opts[:host]}:#{opts[:port]}".downcase
|
100
100
|
Front.set(:address, address)
|
101
|
-
|
102
|
-
|
103
|
-
)
|
101
|
+
entrance = Entrance.new(wallets, remotes, copies, address, log: @log)
|
102
|
+
Front.set(:entrance, entrance)
|
104
103
|
Front.set(:root, Dir.pwd)
|
105
104
|
Front.set(:port, opts['bind-port'])
|
106
105
|
Front.set(:reboot, !opts['never-reboot'])
|
data/lib/zold/commands/push.rb
CHANGED
@@ -26,6 +26,7 @@ require_relative 'args'
|
|
26
26
|
require_relative '../log'
|
27
27
|
require_relative '../id'
|
28
28
|
require_relative '../http'
|
29
|
+
require_relative '../atomic_file'
|
29
30
|
|
30
31
|
# PUSH command.
|
31
32
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -77,7 +78,7 @@ Available options:"
|
|
77
78
|
return 0
|
78
79
|
end
|
79
80
|
start = Time.now
|
80
|
-
content =
|
81
|
+
content = AtomicFile.new(wallet.path).read
|
81
82
|
response = r.http("/wallet/#{wallet.id}#{opts['sync'] ? '?sync=true' : ''}").put(content)
|
82
83
|
if response.code == '304'
|
83
84
|
@log.info("#{r}: same version of #{wallet.id} there")
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -141,7 +141,7 @@ Available options:"
|
|
141
141
|
|
142
142
|
def trim(opts)
|
143
143
|
@remotes.all.each do |r|
|
144
|
-
remove(r[:host], r[:port], opts) if r[:errors] >
|
144
|
+
remove(r[:host], r[:port], opts) if r[:errors] > Remotes::TOLERANCE
|
145
145
|
end
|
146
146
|
@log.info("The list of remotes trimmed, #{@remotes.all.count} nodes left there")
|
147
147
|
end
|
data/lib/zold/copies.rb
CHANGED
data/lib/zold/key.rb
CHANGED
@@ -22,6 +22,7 @@ gem 'openssl'
|
|
22
22
|
require 'openssl'
|
23
23
|
require 'base64'
|
24
24
|
require 'tempfile'
|
25
|
+
require_relative 'atomic_file'
|
25
26
|
|
26
27
|
# The RSA key (either private or public).
|
27
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -35,7 +36,7 @@ module Zold
|
|
35
36
|
unless file.nil?
|
36
37
|
path = File.expand_path(file)
|
37
38
|
raise "Can't find RSA key at #{file} (#{path})" unless File.exist?(path)
|
38
|
-
return
|
39
|
+
return AtomicFile.new(path).read
|
39
40
|
end
|
40
41
|
unless text.nil?
|
41
42
|
return text if text.start_with?('-----')
|
data/lib/zold/node/entrance.rb
CHANGED
@@ -44,7 +44,29 @@ module Zold
|
|
44
44
|
@address = address
|
45
45
|
@log = log
|
46
46
|
@semaphores = Concurrent::Map.new
|
47
|
+
@push_mutex = Mutex.new
|
48
|
+
@modified = Set.new
|
47
49
|
@pool = Concurrent::FixedThreadPool.new(16, max_queue: 64, fallback_policy: :abort)
|
50
|
+
@pushes = Concurrent::FixedThreadPool.new(1, max_queue: 64, fallback_policy: :abort)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_json
|
54
|
+
{
|
55
|
+
'semaphores': @semaphores.size,
|
56
|
+
'modified': @modified.length,
|
57
|
+
'pool': {
|
58
|
+
'completed_task_count': @pool.completed_task_count,
|
59
|
+
'largest_length': @pool.largest_length,
|
60
|
+
'length': @pool.length,
|
61
|
+
'queue_length': @pool.queue_length
|
62
|
+
},
|
63
|
+
'pushes': {
|
64
|
+
'completed_task_count': @pushes.completed_task_count,
|
65
|
+
'largest_length': @pushes.largest_length,
|
66
|
+
'length': @pushes.length,
|
67
|
+
'queue_length': @pushes.queue_length
|
68
|
+
}
|
69
|
+
}
|
48
70
|
end
|
49
71
|
|
50
72
|
def push(id, body, sync: true)
|
@@ -75,6 +97,9 @@ module Zold
|
|
75
97
|
end
|
76
98
|
end
|
77
99
|
|
100
|
+
private
|
101
|
+
|
102
|
+
# Returns a list of modifed wallets (as Zold::Id)
|
78
103
|
def push_sync(id, body)
|
79
104
|
@semaphores.put_if_absent(id, Mutex.new)
|
80
105
|
@semaphores.get(id).synchronize do
|
@@ -85,6 +110,7 @@ module Zold
|
|
85
110
|
end
|
86
111
|
end
|
87
112
|
|
113
|
+
# Returns a list of modifed wallets (as Zold::Id)
|
88
114
|
def push_unsafe(id, body)
|
89
115
|
copies = Copies.new(File.join(@copies, id.to_s))
|
90
116
|
copies.add(body, '0.0.0.0', Remotes::PORT, 0)
|
@@ -96,10 +122,19 @@ module Zold
|
|
96
122
|
).run(['merge', id.to_s])
|
97
123
|
Clean.new(wallets: @wallets, copies: copies.root, log: @log).run(['clean', id.to_s])
|
98
124
|
copies.remove('remote', Remotes::PORT)
|
99
|
-
|
100
|
-
|
101
|
-
).run(['push', "--ignore-node=#{@address}"] + modified.map(&:to_s))
|
125
|
+
@push_mutex.synchronize { @modified += modified }
|
126
|
+
@pushes.post { push_one } if @pushes.length < 2
|
102
127
|
modified
|
103
128
|
end
|
129
|
+
|
130
|
+
def push_one
|
131
|
+
@push_mutex.synchronize do
|
132
|
+
id = @modified.to_a[0]
|
133
|
+
return if id.nil?
|
134
|
+
Push.new(
|
135
|
+
wallets: @wallets, remotes: @remotes, log: @log
|
136
|
+
).run(['push', "--ignore-node=#{@address}"] + [id.to_s])
|
137
|
+
end
|
138
|
+
end
|
104
139
|
end
|
105
140
|
end
|
data/lib/zold/node/farm.rb
CHANGED
data/lib/zold/node/front.rb
CHANGED
@@ -29,6 +29,7 @@ require_relative '../wallet'
|
|
29
29
|
require_relative '../log'
|
30
30
|
require_relative '../id'
|
31
31
|
require_relative '../http'
|
32
|
+
require_relative '../atomic_file'
|
32
33
|
|
33
34
|
# The web front of the node.
|
34
35
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -40,7 +41,7 @@ module Zold
|
|
40
41
|
configure do
|
41
42
|
set :bind, '0.0.0.0'
|
42
43
|
set :suppress_messages, true
|
43
|
-
set :dump_errors,
|
44
|
+
set :dump_errors, false
|
44
45
|
set :start, Time.now
|
45
46
|
set :lock, false
|
46
47
|
set :show_exceptions, false
|
@@ -123,6 +124,7 @@ module Zold
|
|
123
124
|
wallets: settings.wallets.all.count,
|
124
125
|
remotes: settings.remotes.all.count,
|
125
126
|
farm: settings.farm.to_json,
|
127
|
+
entrance: settings.entrance.to_json,
|
126
128
|
date: `date --iso-8601=seconds -u`.strip,
|
127
129
|
hours_alive: ((Time.now - settings.start) / (60 * 60)).round(2),
|
128
130
|
home: 'https://www.zold.io'
|
@@ -137,7 +139,7 @@ module Zold
|
|
137
139
|
{
|
138
140
|
version: VERSION,
|
139
141
|
score: score.to_h,
|
140
|
-
body:
|
142
|
+
body: AtomicFile.new(wallet.path).read
|
141
143
|
}.to_json
|
142
144
|
end
|
143
145
|
|
@@ -146,7 +148,7 @@ module Zold
|
|
146
148
|
wallet = settings.wallets.find(id)
|
147
149
|
request.body.rewind
|
148
150
|
body = request.body.read
|
149
|
-
if wallet.exists? &&
|
151
|
+
if wallet.exists? && AtomicFile.new(wallet.path).read == body
|
150
152
|
status 304
|
151
153
|
return
|
152
154
|
end
|
data/lib/zold/patch.rb
CHANGED
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
require_relative 'wallet'
|
22
22
|
require_relative 'signature'
|
23
|
+
require_relative 'atomic_file'
|
23
24
|
|
24
25
|
# Patch.
|
25
26
|
#
|
@@ -54,11 +55,11 @@ module Zold
|
|
54
55
|
# Returns TRUE if the file was actually modified
|
55
56
|
def save(file, overwrite: false)
|
56
57
|
before = ''
|
57
|
-
before =
|
58
|
+
before = AtomicFile.new(file).read if File.exist?(file)
|
58
59
|
wallet = Wallet.new(file)
|
59
60
|
wallet.init(@id, @key, overwrite: overwrite, network: @network)
|
60
61
|
@txns.each { |t| wallet.add(t) }
|
61
|
-
after =
|
62
|
+
after = AtomicFile.new(file).read
|
62
63
|
before != after
|
63
64
|
end
|
64
65
|
end
|
data/lib/zold/remotes.rb
CHANGED
@@ -34,6 +34,9 @@ module Zold
|
|
34
34
|
# The default TCP port all nodes are supposed to use.
|
35
35
|
PORT = 4096
|
36
36
|
|
37
|
+
# At what amount of errors we delete the remote automatically
|
38
|
+
TOLERANCE = 50
|
39
|
+
|
37
40
|
# Empty, for standalone mode
|
38
41
|
class Empty
|
39
42
|
def all
|
@@ -138,12 +141,21 @@ module Zold
|
|
138
141
|
yield Remotes::Remote.new(r[:host], r[:port], score, log: log)
|
139
142
|
rescue StandardError => e
|
140
143
|
error(r[:host], r[:port])
|
141
|
-
|
144
|
+
errors = errors(r[:host], r[:port])
|
145
|
+
log.info("#{Rainbow("#{r[:host]}:#{r[:port]}").red}: #{e.message}; errors=#{errors}")
|
142
146
|
log.debug(e.backtrace[0..5].join("\n\t"))
|
147
|
+
remove(r[:host], r[:port]) if errors > Remotes::TOLERANCE
|
143
148
|
end
|
144
149
|
end
|
145
150
|
end
|
146
151
|
|
152
|
+
def errors(host, port = Remotes::PORT)
|
153
|
+
raise 'Port has to be of type Integer' unless port.is_a?(Integer)
|
154
|
+
list = load
|
155
|
+
raise "#{host}:#{port} is absent among #{list.count} remotes" unless exists?(host, port)
|
156
|
+
list.find { |r| r[:host] == host.downcase && r[:port] == port }[:errors]
|
157
|
+
end
|
158
|
+
|
147
159
|
def error(host, port = Remotes::PORT)
|
148
160
|
raise 'Port has to be of type Integer' unless port.is_a?(Integer)
|
149
161
|
list = load
|
data/lib/zold/version.rb
CHANGED
data/lib/zold/wallet.rb
CHANGED
data/test/node/test_entrance.rb
CHANGED
@@ -34,6 +34,14 @@ require_relative '../../lib/zold/commands/pay'
|
|
34
34
|
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
35
35
|
# License:: MIT
|
36
36
|
class TestEntrance < Minitest::Test
|
37
|
+
def test_renders_json
|
38
|
+
FakeHome.new.run do |home|
|
39
|
+
wallet = home.create_wallet(Zold::Id.new)
|
40
|
+
entrance = Zold::Entrance.new(home.wallets, home.remotes, home.copies(wallet).root, 'x', log: test_log)
|
41
|
+
assert_equal(0, entrance.to_json[:modified])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
37
45
|
def test_pushes_wallet
|
38
46
|
sid = Zold::Id.new
|
39
47
|
tid = Zold::Id.new
|