zold 0.11.7 → 0.11.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|