zold 0.16.17 → 0.16.18
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/http.rb +6 -6
- data/lib/zold/id.rb +1 -0
- data/lib/zold/node/async_entrance.rb +20 -24
- data/lib/zold/node/entrance.rb +1 -1
- data/lib/zold/node/farmers.rb +2 -2
- data/lib/zold/node/front.rb +2 -2
- data/lib/zold/node/nodup_entrance.rb +8 -21
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallet.rb +6 -1
- data/test/test_http.rb +21 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: de86dbcab88573c76088a862afd47563bebee0d62df73b695bdae79dc2e47778
|
|
4
|
+
data.tar.gz: 76f9b1a004ff1ef24acf833626b128bff9ac7663e16bc10c7a476e4667b349fc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 68cf2ad85d6eeaf93cb9d32d1e84f8c25c96f70826ca4dc9e68140e89c32bd9d9e584fcc94e9ccc7fbfcaec0e1e9b2c3c2a51313f717af97da577bf517ae7ade
|
|
7
|
+
data.tar.gz: 2c45d5fee9bf53f9e2e09e9e961c3004755574fd23a5840c93767b15beba9b3c236464fd299b70b39b846a3126b4ce66792bb29f608158f5af69fbc94ae3bf9c
|
data/lib/zold/http.rb
CHANGED
|
@@ -55,10 +55,10 @@ module Zold
|
|
|
55
55
|
PROTOCOL_HEADER = 'X-Zold-Protocol'
|
|
56
56
|
|
|
57
57
|
# Read timeout in seconds
|
|
58
|
-
READ_TIMEOUT =
|
|
58
|
+
READ_TIMEOUT = 1
|
|
59
59
|
|
|
60
60
|
# Connect timeout in seconds
|
|
61
|
-
CONNECT_TIMEOUT = 0.
|
|
61
|
+
CONNECT_TIMEOUT = 0.4
|
|
62
62
|
|
|
63
63
|
def initialize(uri:, score: Score::ZERO, network: 'test')
|
|
64
64
|
@uri = uri.is_a?(URI) ? uri : URI(uri)
|
|
@@ -69,11 +69,11 @@ module Zold
|
|
|
69
69
|
def get(timeout: Http::READ_TIMEOUT + Http::CONNECT_TIMEOUT)
|
|
70
70
|
http = Net::HTTP.new(@uri.host, @uri.port)
|
|
71
71
|
http.use_ssl = @uri.scheme == 'https'
|
|
72
|
-
http.read_timeout =
|
|
72
|
+
http.read_timeout = timeout
|
|
73
73
|
http.open_timeout = Http::CONNECT_TIMEOUT
|
|
74
74
|
path = @uri.path
|
|
75
75
|
path += '?' + @uri.query if @uri.query
|
|
76
|
-
Timeout.timeout(timeout) do
|
|
76
|
+
Timeout.timeout(timeout + Http::CONNECT_TIMEOUT) do
|
|
77
77
|
http.request_get(path, headers)
|
|
78
78
|
end
|
|
79
79
|
rescue StandardError => e
|
|
@@ -83,11 +83,11 @@ module Zold
|
|
|
83
83
|
def put(body, timeout: Http::READ_TIMEOUT + Http::CONNECT_TIMEOUT)
|
|
84
84
|
http = Net::HTTP.new(@uri.host, @uri.port)
|
|
85
85
|
http.use_ssl = @uri.scheme == 'https'
|
|
86
|
-
http.read_timeout =
|
|
86
|
+
http.read_timeout = timeout
|
|
87
87
|
http.open_timeout = Http::CONNECT_TIMEOUT
|
|
88
88
|
path = @uri.path
|
|
89
89
|
path += '?' + @uri.query if @uri.query
|
|
90
|
-
Timeout.timeout(timeout) do
|
|
90
|
+
Timeout.timeout(timeout + Http::CONNECT_TIMEOUT) do
|
|
91
91
|
http.request_put(
|
|
92
92
|
path, body,
|
|
93
93
|
headers.merge(
|
data/lib/zold/id.rb
CHANGED
|
@@ -38,28 +38,33 @@ module Zold
|
|
|
38
38
|
class AsyncEntrance
|
|
39
39
|
def initialize(entrance, dir, log: Log::Quiet.new, threads: [Concurrent.processor_count, 4].max)
|
|
40
40
|
@entrance = entrance
|
|
41
|
-
@dir = dir
|
|
41
|
+
@dir = File.expand_path(dir)
|
|
42
42
|
@log = log
|
|
43
43
|
@total = threads
|
|
44
|
-
@
|
|
44
|
+
@queue = Queue.new
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def to_json
|
|
48
48
|
@entrance.to_json.merge(
|
|
49
|
-
'queue': queue.
|
|
49
|
+
'queue': @queue.size,
|
|
50
50
|
'threads': @threads.count
|
|
51
51
|
)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def start
|
|
55
55
|
raise 'Block must be given to start()' unless block_given?
|
|
56
|
+
FileUtils.mkdir_p(@dir)
|
|
57
|
+
DirItems.new(@dir).fetch.select { |f| f =~ /^[0-9a-f]{16}-/ }.each do |f|
|
|
58
|
+
file = File.join(@dir, f)
|
|
59
|
+
id = f.split('-')[0]
|
|
60
|
+
@queue << { id: Id.new(id), file: file }
|
|
61
|
+
end
|
|
62
|
+
@log.info("#{@queue.size} wallets pre-loaded into async_entrace from #{@dir}") unless @queue.size.zero?
|
|
56
63
|
@entrance.start do
|
|
57
|
-
FileUtils.mkdir_p(@dir)
|
|
58
64
|
@threads = (0..@total - 1).map do |i|
|
|
59
65
|
Thread.start do
|
|
60
66
|
Endless.new("async-e##{i}", log: @log).run do
|
|
61
67
|
take
|
|
62
|
-
sleep(1)
|
|
63
68
|
end
|
|
64
69
|
end
|
|
65
70
|
end
|
|
@@ -73,14 +78,15 @@ module Zold
|
|
|
73
78
|
|
|
74
79
|
# Always returns an array with a single ID of the pushed wallet
|
|
75
80
|
def push(id, body)
|
|
76
|
-
raise "Queue is too long (#{queue.
|
|
81
|
+
raise "Queue is too long (#{@queue.size} wallets), try again later" if @queue.size > 256
|
|
77
82
|
start = Time.now
|
|
78
83
|
loop do
|
|
79
84
|
uuid = SecureRandom.uuid
|
|
80
85
|
file = File.join(@dir, "#{id}-#{uuid}")
|
|
81
86
|
next if File.exist?(file)
|
|
82
87
|
IO.write(file, body)
|
|
83
|
-
@
|
|
88
|
+
@queue << { id: id, file: file }
|
|
89
|
+
@log.debug("Added #{id}/#{Size.new(body.length)} to the queue at pos.#{@queue.size} \
|
|
84
90
|
in #{Age.new(start, limit: 0.05)}: #{uuid}")
|
|
85
91
|
break
|
|
86
92
|
end
|
|
@@ -91,23 +97,13 @@ in #{Age.new(start, limit: 0.05)}: #{uuid}")
|
|
|
91
97
|
|
|
92
98
|
def take
|
|
93
99
|
start = Time.now
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
FileUtils.rm_f(file)
|
|
102
|
-
[id, body]
|
|
103
|
-
end
|
|
104
|
-
@entrance.push(Id.new(id), body)
|
|
105
|
-
@log.debug("Pushed #{id}/#{Size.new(body.length)} to #{@entrance.class.name} \
|
|
106
|
-
in #{Age.new(start, limit: 0.1)} (#{queue.count} still in the queue)")
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def queue
|
|
110
|
-
DirItems.new(@dir).fetch.select { |f| f =~ /^[0-9a-f]{16}-/ }
|
|
100
|
+
item = @queue.pop
|
|
101
|
+
Thread.current.thread_variable_set(:wallet, item[:id].to_s)
|
|
102
|
+
body = IO.read(item[:file])
|
|
103
|
+
FileUtils.rm_f(item[:file])
|
|
104
|
+
@entrance.push(item[:id], body)
|
|
105
|
+
@log.debug("Pushed #{item[:id]}/#{Size.new(body.length)} to #{@entrance.class.name} \
|
|
106
|
+
in #{Age.new(start, limit: 0.1)} (#{@queue.size} still in the queue)")
|
|
111
107
|
end
|
|
112
108
|
end
|
|
113
109
|
end
|
data/lib/zold/node/entrance.rb
CHANGED
|
@@ -92,7 +92,7 @@ module Zold
|
|
|
92
92
|
@history.shift if @history.length >= 16
|
|
93
93
|
@speed.shift if @speed.length >= 64
|
|
94
94
|
@wallets.find(id) do |wallet|
|
|
95
|
-
@history << "#{
|
|
95
|
+
@history << "#{sec}/#{modified.count}/#{wallet.mnemo}"
|
|
96
96
|
end
|
|
97
97
|
@speed << sec
|
|
98
98
|
end
|
data/lib/zold/node/farmers.rb
CHANGED
|
@@ -71,7 +71,7 @@ for #{score.value}/#{score.strength} at #{score.host}:#{score.port}")
|
|
|
71
71
|
buffer = +''
|
|
72
72
|
loop do
|
|
73
73
|
begin
|
|
74
|
-
buffer << stdout.read_nonblock(1024)
|
|
74
|
+
buffer << stdout.read_nonblock(16 * 1024)
|
|
75
75
|
# rubocop:disable Lint/HandleExceptions
|
|
76
76
|
rescue IO::WaitReadable => _
|
|
77
77
|
# rubocop:enable Lint/HandleExceptions
|
|
@@ -85,7 +85,7 @@ for #{score.value}/#{score.strength} at #{score.host}:#{score.port}")
|
|
|
85
85
|
raise "Failed to calculate the score (##{thr.value}): #{buffer}" unless thr.value.to_i.zero?
|
|
86
86
|
break
|
|
87
87
|
end
|
|
88
|
-
sleep(
|
|
88
|
+
sleep(1)
|
|
89
89
|
Thread.current.thread_variable_set(:buffer, buffer.length.to_s)
|
|
90
90
|
end
|
|
91
91
|
after = Score.parse(buffer.strip)
|
data/lib/zold/node/front.rb
CHANGED
|
@@ -230,7 +230,7 @@ in #{Age.new(@start, limit: 1)}")
|
|
|
230
230
|
score: score.to_h,
|
|
231
231
|
wallets: total_wallets,
|
|
232
232
|
mtime: wallet.mtime.utc.iso8601,
|
|
233
|
-
size:
|
|
233
|
+
size: wallet.size,
|
|
234
234
|
digest: wallet.digest,
|
|
235
235
|
copies: Copies.new(File.join(settings.copies, id)).all.count,
|
|
236
236
|
balance: wallet.balance.to_i,
|
|
@@ -313,7 +313,7 @@ in #{Age.new(@start, limit: 1)}")
|
|
|
313
313
|
"Balance: #{wallet.balance.to_zld(8)} ZLD (#{wallet.balance.to_i} zents)",
|
|
314
314
|
"Transactions: #{wallet.txns.count}",
|
|
315
315
|
"Taxes: #{Tax.new(wallet).paid} paid, the debt is #{Tax.new(wallet).debt}",
|
|
316
|
-
"File size: #{
|
|
316
|
+
"File size: #{wallet.size} bytes (#{Copies.new(File.join(settings.copies, id)).all.count} copies)",
|
|
317
317
|
"Modified: #{wallet.mtime.utc.iso8601} (#{Age.new(wallet.mtime.utc.iso8601)} ago)",
|
|
318
318
|
"Digest: #{wallet.digest}"
|
|
319
319
|
].join("\n")
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
23
|
require 'tempfile'
|
|
24
|
+
require 'openssl'
|
|
24
25
|
require_relative '../log'
|
|
25
26
|
require_relative '../size'
|
|
26
27
|
require_relative '../wallet'
|
|
@@ -33,11 +34,8 @@ module Zold
|
|
|
33
34
|
# The safe entrance
|
|
34
35
|
class NoDupEntrance
|
|
35
36
|
def initialize(entrance, wallets, log: Log::Quiet.new)
|
|
36
|
-
raise 'Entrance can\'t be nil' if entrance.nil?
|
|
37
37
|
@entrance = entrance
|
|
38
|
-
raise 'Wallets can\'t be nil' if wallets.nil?
|
|
39
38
|
@wallets = wallets
|
|
40
|
-
raise 'Log can\'t be nil' if log.nil?
|
|
41
39
|
@log = log
|
|
42
40
|
end
|
|
43
41
|
|
|
@@ -52,25 +50,14 @@ module Zold
|
|
|
52
50
|
|
|
53
51
|
# Returns a list of modifed wallets (as Zold::Id)
|
|
54
52
|
def push(id, body)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
wallet = Wallet.new(f.path)
|
|
61
|
-
wallet.refurbish
|
|
62
|
-
after = IO.read(wallet.path)
|
|
63
|
-
before = @wallets.find(id) do |w|
|
|
64
|
-
w.exists? ? IO.read(w.path).to_s : ''
|
|
65
|
-
end
|
|
66
|
-
if before == after
|
|
67
|
-
@log.info("Duplicate of #{Size.new(after.length)} #{wallet.mnemo} ignored")
|
|
68
|
-
return []
|
|
69
|
-
end
|
|
70
|
-
@log.info("New content for #{wallet.mnemo} arrived, \
|
|
71
|
-
#{Size.new(before.length)} before and #{Size.new(after.length)} after")
|
|
72
|
-
@entrance.push(id, body)
|
|
53
|
+
before = @wallets.find(id) { |w| w.exists? ? w.digest : '' }
|
|
54
|
+
after = OpenSSL::Digest::SHA256.new(body).hexdigest
|
|
55
|
+
if before == after
|
|
56
|
+
@log.debug("Duplicate of #{id} ignored (#{Size.new(body.length)} bytes)")
|
|
57
|
+
return []
|
|
73
58
|
end
|
|
59
|
+
@log.debug("New content for #{id} arrived (#{Size.new(body.length)} bytes)")
|
|
60
|
+
@entrance.push(id, body)
|
|
74
61
|
end
|
|
75
62
|
end
|
|
76
63
|
end
|
data/lib/zold/version.rb
CHANGED
data/lib/zold/wallet.rb
CHANGED
|
@@ -72,7 +72,7 @@ module Zold
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def mnemo
|
|
75
|
-
"#{id}/#{balance.to_zld(4)}/#{txns.count}t/#{digest[0, 6]}/#{Size.new(
|
|
75
|
+
"#{id}/#{balance.to_zld(4)}/#{txns.count}t/#{digest[0, 6]}/#{Size.new(size)}"
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def to_text
|
|
@@ -195,6 +195,11 @@ module Zold
|
|
|
195
195
|
list.empty? ? 0 : (Time.now - list.min_by(&:date).date) / (60 * 60)
|
|
196
196
|
end
|
|
197
197
|
|
|
198
|
+
# Size of the wallet file in bytes
|
|
199
|
+
def size
|
|
200
|
+
File.size(path)
|
|
201
|
+
end
|
|
202
|
+
|
|
198
203
|
def txns
|
|
199
204
|
@txns.fetch
|
|
200
205
|
end
|
data/test/test_http.rb
CHANGED
|
@@ -25,6 +25,7 @@ require 'tmpdir'
|
|
|
25
25
|
require 'uri'
|
|
26
26
|
require 'webmock/minitest'
|
|
27
27
|
require 'zold/score'
|
|
28
|
+
require_relative 'test__helper'
|
|
28
29
|
require_relative '../lib/zold/http'
|
|
29
30
|
|
|
30
31
|
# Http test.
|
|
@@ -78,6 +79,26 @@ class TestHttp < Zold::Test
|
|
|
78
79
|
assert_equal('599', res.code)
|
|
79
80
|
end
|
|
80
81
|
|
|
82
|
+
def test_doesnt_terminate_on_long_call
|
|
83
|
+
require 'random-port'
|
|
84
|
+
WebMock.allow_net_connect!
|
|
85
|
+
RandomPort::Pool::SINGLETON.acquire do |port|
|
|
86
|
+
thread = Thread.start do
|
|
87
|
+
server = TCPServer.new(port)
|
|
88
|
+
loop do
|
|
89
|
+
client = server.accept
|
|
90
|
+
sleep 1
|
|
91
|
+
client.puts("HTTP/1.1 200 OK\nContent-Length: 4\n\nGood")
|
|
92
|
+
client.close
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
res = Zold::Http.new(uri: "http://localhost:#{port}/").get(timeout: 2)
|
|
96
|
+
assert_equal('200', res.code, res)
|
|
97
|
+
thread.kill
|
|
98
|
+
thread.join
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
81
102
|
def test_sends_valid_version_header
|
|
82
103
|
stub_request(:get, 'http://some-host-3/')
|
|
83
104
|
.with(headers: { 'X-Zold-Version' => Zold::VERSION })
|
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.16.
|
|
4
|
+
version: 0.16.18
|
|
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-11-
|
|
11
|
+
date: 2018-11-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|