baza.rb 0.9.11 → 0.10.0
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/.github/workflows/typos.yml +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +21 -21
- data/lib/baza-rb/version.rb +1 -1
- data/lib/baza-rb.rb +43 -30
- data/test/test_baza-rb.rb +43 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3925181637ee67621a9013cda972f3de775c644d67b530573814d40ff064f6f1
|
4
|
+
data.tar.gz: 0d883da9c8f1cc1c4538d303fc3e864e81f4145e443011c7277dc06673bb448d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b21df150b5c2c58efce934266400d589adec2d8fb594a43202801f4ae8050b182feda6b72c5b85a1490a6242483f093fc448323a285c51a0db383b166f4c198
|
7
|
+
data.tar.gz: fdf81673a2ac0a524ab0abd614fba9dae23a791dbff7311aed8d77afa001269b9cd571d84f57fde3f5f6cd7b4f018c6a8b8c79ff1eb78c326825aa3941ac3f39
|
data/.github/workflows/typos.yml
CHANGED
data/Gemfile
CHANGED
@@ -23,7 +23,7 @@ gem 'rubocop-minitest', '~>0.38', require: false
|
|
23
23
|
gem 'rubocop-performance', '~>1.23', require: false
|
24
24
|
gem 'rubocop-rake', '~>0.7', require: false
|
25
25
|
gem 'simplecov', '~>0.22', require: false
|
26
|
-
gem 'simplecov-cobertura', '~>
|
26
|
+
gem 'simplecov-cobertura', '~>3.0', require: false
|
27
27
|
gem 'sinatra', '~>4.1', require: false
|
28
28
|
gem 'wait_for', '~>0.1', require: false
|
29
29
|
gem 'webmock', '~>3.24', require: false
|
data/Gemfile.lock
CHANGED
@@ -30,13 +30,13 @@ GEM
|
|
30
30
|
rexml
|
31
31
|
decoor (0.1.0)
|
32
32
|
docile (1.4.1)
|
33
|
-
elapsed (0.
|
34
|
-
loog (
|
35
|
-
tago (
|
33
|
+
elapsed (0.2.0)
|
34
|
+
loog (~> 0.6)
|
35
|
+
tago (~> 0.1)
|
36
36
|
ellipsized (0.3.0)
|
37
37
|
ethon (0.16.0)
|
38
38
|
ffi (>= 1.15.0)
|
39
|
-
factbase (0.
|
39
|
+
factbase (0.14.3)
|
40
40
|
backtrace (~> 0.4)
|
41
41
|
decoor (~> 0.0)
|
42
42
|
ellipsized (~> 0.3)
|
@@ -47,7 +47,7 @@ GEM
|
|
47
47
|
others (~> 0.0)
|
48
48
|
tago (~> 0.0)
|
49
49
|
yaml (~> 0.3)
|
50
|
-
faraday (2.13.
|
50
|
+
faraday (2.13.4)
|
51
51
|
faraday-net_http (>= 2.0, < 3.5)
|
52
52
|
json
|
53
53
|
logger
|
@@ -65,7 +65,7 @@ GEM
|
|
65
65
|
ffi (1.17.2-x86_64-linux-gnu)
|
66
66
|
hashdiff (1.2.0)
|
67
67
|
iri (0.11.2)
|
68
|
-
json (2.
|
68
|
+
json (2.13.2)
|
69
69
|
language_server-protocol (3.17.0.5)
|
70
70
|
lint_roller (1.1.0)
|
71
71
|
logger (1.7.0)
|
@@ -78,30 +78,30 @@ GEM
|
|
78
78
|
minitest (>= 5.0)
|
79
79
|
ruby-progressbar
|
80
80
|
multipart-post (2.4.1)
|
81
|
-
mustermann (3.0.
|
81
|
+
mustermann (3.0.4)
|
82
82
|
ruby2_keywords (~> 0.0.1)
|
83
83
|
net-http (0.6.0)
|
84
84
|
uri
|
85
85
|
nio4r (2.7.4)
|
86
|
-
nokogiri (1.18.
|
86
|
+
nokogiri (1.18.9-arm64-darwin)
|
87
87
|
racc (~> 1.4)
|
88
|
-
nokogiri (1.18.
|
88
|
+
nokogiri (1.18.9-x64-mingw-ucrt)
|
89
89
|
racc (~> 1.4)
|
90
|
-
nokogiri (1.18.
|
90
|
+
nokogiri (1.18.9-x86_64-darwin)
|
91
91
|
racc (~> 1.4)
|
92
|
-
nokogiri (1.18.
|
92
|
+
nokogiri (1.18.9-x86_64-linux-gnu)
|
93
93
|
racc (~> 1.4)
|
94
94
|
online (0.0.1)
|
95
95
|
timeout (~> 0.4)
|
96
96
|
os (1.1.4)
|
97
97
|
others (0.1.1)
|
98
98
|
parallel (1.27.0)
|
99
|
-
parser (3.3.
|
99
|
+
parser (3.3.9.0)
|
100
100
|
ast (~> 2.4.1)
|
101
101
|
racc
|
102
102
|
prism (1.4.0)
|
103
103
|
public_suffix (6.0.2)
|
104
|
-
puma (6.6.
|
104
|
+
puma (6.6.1)
|
105
105
|
nio4r (~> 2.0)
|
106
106
|
qbash (0.4.5)
|
107
107
|
backtrace (> 0)
|
@@ -109,7 +109,7 @@ GEM
|
|
109
109
|
loog (> 0)
|
110
110
|
tago (> 0)
|
111
111
|
racc (1.8.1)
|
112
|
-
rack (3.
|
112
|
+
rack (3.2.0)
|
113
113
|
rack-protection (4.1.1)
|
114
114
|
base64 (>= 0.1.0)
|
115
115
|
logger (>= 1.6.0)
|
@@ -123,10 +123,10 @@ GEM
|
|
123
123
|
rake (13.3.0)
|
124
124
|
random-port (0.7.5)
|
125
125
|
tago (> 0)
|
126
|
-
regexp_parser (2.
|
126
|
+
regexp_parser (2.11.0)
|
127
127
|
retries (0.0.5)
|
128
128
|
rexml (3.4.1)
|
129
|
-
rubocop (1.
|
129
|
+
rubocop (1.79.2)
|
130
130
|
json (~> 2.3)
|
131
131
|
language_server-protocol (~> 3.17.0.2)
|
132
132
|
lint_roller (~> 1.1.0)
|
@@ -134,10 +134,10 @@ GEM
|
|
134
134
|
parser (>= 3.3.0.2)
|
135
135
|
rainbow (>= 2.2.2, < 4.0)
|
136
136
|
regexp_parser (>= 2.9.3, < 3.0)
|
137
|
-
rubocop-ast (>= 1.
|
137
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
138
138
|
ruby-progressbar (~> 1.7)
|
139
139
|
unicode-display_width (>= 2.4.0, < 4.0)
|
140
|
-
rubocop-ast (1.
|
140
|
+
rubocop-ast (1.46.0)
|
141
141
|
parser (>= 3.3.7.2)
|
142
142
|
prism (~> 1.4)
|
143
143
|
rubocop-minitest (0.38.1)
|
@@ -157,10 +157,10 @@ GEM
|
|
157
157
|
docile (~> 1.1)
|
158
158
|
simplecov-html (~> 0.11)
|
159
159
|
simplecov_json_formatter (~> 0.1)
|
160
|
-
simplecov-cobertura (
|
160
|
+
simplecov-cobertura (3.0.0)
|
161
161
|
rexml
|
162
162
|
simplecov (~> 0.19)
|
163
|
-
simplecov-html (0.13.
|
163
|
+
simplecov-html (0.13.2)
|
164
164
|
simplecov_json_formatter (0.1.4)
|
165
165
|
sinatra (4.1.1)
|
166
166
|
logger (>= 1.6.0)
|
@@ -215,7 +215,7 @@ DEPENDENCIES
|
|
215
215
|
rubocop-performance (~> 1.23)
|
216
216
|
rubocop-rake (~> 0.7)
|
217
217
|
simplecov (~> 0.22)
|
218
|
-
simplecov-cobertura (~>
|
218
|
+
simplecov-cobertura (~> 3.0)
|
219
219
|
sinatra (~> 4.1)
|
220
220
|
wait_for (~> 0.1)
|
221
221
|
webmock (~> 3.24)
|
data/lib/baza-rb/version.rb
CHANGED
data/lib/baza-rb.rb
CHANGED
@@ -57,9 +57,10 @@ class BazaRb
|
|
57
57
|
# @param [Boolean] ssl Whether to use SSL/HTTPS (default: true)
|
58
58
|
# @param [Float] timeout Connection and request timeout in seconds (default: 30)
|
59
59
|
# @param [Integer] retries Number of retries on connection failure (default: 3)
|
60
|
+
# @param [Integer] pause The factor on pause (<1 means faster, >1 means slower)
|
60
61
|
# @param [Loog] loog The logging facility (default: Loog::NULL)
|
61
62
|
# @param [Boolean] compress Whether to use GZIP compression for requests/responses (default: true)
|
62
|
-
def initialize(host, port, token, ssl: true, timeout: 30, retries:
|
63
|
+
def initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true)
|
63
64
|
@host = host
|
64
65
|
@port = port
|
65
66
|
@ssl = ssl
|
@@ -67,6 +68,7 @@ class BazaRb
|
|
67
68
|
@timeout = timeout
|
68
69
|
@loog = loog
|
69
70
|
@retries = retries
|
71
|
+
@pause = pause
|
70
72
|
@compress = compress
|
71
73
|
end
|
72
74
|
|
@@ -652,10 +654,10 @@ class BazaRb
|
|
652
654
|
attempt = 0
|
653
655
|
loop do
|
654
656
|
ret = yield
|
655
|
-
if ret.code == 429 && attempt <
|
657
|
+
if ret.code == 429 && attempt < @retries
|
656
658
|
attempt += 1
|
657
|
-
seconds = 2**attempt
|
658
|
-
@loog.info("Server seems to be busy, will sleep for #{seconds}
|
659
|
+
seconds = @pause * (2**attempt)
|
660
|
+
@loog.info("Server seems to be busy, will sleep for #{seconds} (attempt no.#{attempt})...")
|
659
661
|
sleep(seconds)
|
660
662
|
next
|
661
663
|
end
|
@@ -671,10 +673,10 @@ class BazaRb
|
|
671
673
|
attempt = 0
|
672
674
|
loop do
|
673
675
|
ret = yield
|
674
|
-
if ret.code >= 500 && attempt <
|
676
|
+
if ret.code >= 500 && attempt < @retries
|
675
677
|
attempt += 1
|
676
|
-
seconds = 2**attempt
|
677
|
-
@loog.info("Server seems to be in trouble, will sleep for #{seconds}
|
678
|
+
seconds = @pause * (2**attempt)
|
679
|
+
@loog.info("Server seems to be in trouble, will sleep for #{seconds} (attempt no.#{attempt})...")
|
678
680
|
sleep(seconds)
|
679
681
|
next
|
680
682
|
end
|
@@ -788,35 +790,42 @@ class BazaRb
|
|
788
790
|
FileUtils.rm_f(file)
|
789
791
|
FileUtils.touch(file)
|
790
792
|
chunk = 0
|
793
|
+
blanks = [204, 302]
|
791
794
|
elapsed(@loog) do
|
792
795
|
loop do
|
793
|
-
request = Typhoeus::Request.new(
|
794
|
-
uri.to_s,
|
795
|
-
method: :get,
|
796
|
-
headers: headers.merge(
|
797
|
-
'Accept' => '*',
|
798
|
-
'Accept-Encoding' => 'gzip',
|
799
|
-
'Range' => "bytes=#{File.size(file)}-"
|
800
|
-
),
|
801
|
-
connecttimeout: @timeout,
|
802
|
-
timeout: @timeout
|
803
|
-
)
|
804
796
|
slice = ''
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
797
|
+
ret = nil
|
798
|
+
retry_if_server_busy do
|
799
|
+
retry_if_server_failed do
|
800
|
+
slice = ''
|
801
|
+
request = Typhoeus::Request.new(
|
802
|
+
uri.to_s,
|
803
|
+
method: :get,
|
804
|
+
headers: headers.merge(
|
805
|
+
'Accept' => '*',
|
806
|
+
'Accept-Encoding' => 'gzip',
|
807
|
+
'Range' => "bytes=#{File.size(file)}-"
|
808
|
+
),
|
809
|
+
connecttimeout: @timeout,
|
810
|
+
timeout: @timeout
|
811
|
+
)
|
812
|
+
request.on_body do |data|
|
813
|
+
slice += data
|
814
|
+
end
|
815
|
+
retry_it do
|
816
|
+
request.run
|
817
|
+
end
|
818
|
+
ret = request.response
|
819
|
+
end
|
810
820
|
end
|
811
|
-
ret = request.response
|
812
821
|
msg = [
|
813
822
|
"GET #{uri.to_uri.path} #{ret.code}",
|
814
823
|
"#{slice.bytesize} bytes",
|
815
824
|
('in gzip' if ret.headers['Content-Encoding'] == 'gzip'),
|
816
825
|
("ranged as #{ret.headers['Content-Range'].inspect}" if ret.headers['Content-Range'])
|
817
826
|
]
|
818
|
-
ret = checked(ret, [200, 206, 302])
|
819
|
-
next if ret.code
|
827
|
+
ret = checked(ret, [200, 206, 204, 302])
|
828
|
+
next if blanks.include?(ret.code)
|
820
829
|
if ret.headers['Content-Encoding'] == 'gzip'
|
821
830
|
begin
|
822
831
|
slice = unzip(slice)
|
@@ -882,10 +891,14 @@ class BazaRb
|
|
882
891
|
ret =
|
883
892
|
retry_it do
|
884
893
|
checked(
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
894
|
+
retry_if_server_failed do
|
895
|
+
retry_if_server_busy do
|
896
|
+
Typhoeus::Request.put(
|
897
|
+
uri.to_s,
|
898
|
+
params
|
899
|
+
)
|
900
|
+
end
|
901
|
+
end
|
889
902
|
)
|
890
903
|
end
|
891
904
|
sent += params[:body].bytesize
|
data/test/test_baza-rb.rb
CHANGED
@@ -354,18 +354,6 @@ class TestBazaRb < Minitest::Test
|
|
354
354
|
end
|
355
355
|
end
|
356
356
|
|
357
|
-
def test_push_with_server_failure
|
358
|
-
WebMock.disable_net_connect!
|
359
|
-
stub_request(:put, 'https://example.org/push/foo')
|
360
|
-
.to_return(status: 503, body: 'oops', headers: { 'X-Zerocracy-Failure': 'the failure' })
|
361
|
-
.to_raise('why second time?')
|
362
|
-
e = assert_raises(StandardError) { fake_baza.push('foo', 'data', []) }
|
363
|
-
[
|
364
|
-
'Invalid response code #503',
|
365
|
-
'"the failure"'
|
366
|
-
].each { |t| assert_includes(e.message, t, "Can't find '#{t}' in #{e.message.inspect}") }
|
367
|
-
end
|
368
|
-
|
369
357
|
def test_real_http
|
370
358
|
WebMock.enable_net_connect!
|
371
359
|
skip('We are offline') unless we_are_online?
|
@@ -705,6 +693,49 @@ class TestBazaRb < Minitest::Test
|
|
705
693
|
assert_equal('testuser', fake_baza.whoami)
|
706
694
|
end
|
707
695
|
|
696
|
+
def test_download_retries_on_busy_server
|
697
|
+
WebMock.disable_net_connect!
|
698
|
+
Dir.mktmpdir do |dir|
|
699
|
+
file = File.join(dir, 'download.txt')
|
700
|
+
attempts = 0
|
701
|
+
stub_request(:get, 'https://example.org:443/file')
|
702
|
+
.with(headers: { 'Range' => 'bytes=0-' })
|
703
|
+
.to_return do |_request|
|
704
|
+
attempts += 1
|
705
|
+
if attempts < 2
|
706
|
+
{ status: 429, body: 'Too Many Requests', headers: {} }
|
707
|
+
else
|
708
|
+
{ status: 200, body: 'success content', headers: {} }
|
709
|
+
end
|
710
|
+
end
|
711
|
+
baza = BazaRb.new('example.org', 443, '000', loog: Loog::NULL, compress: false, timeout: 0.1, pause: 0)
|
712
|
+
baza.send(:download, baza.send(:home).append('file'), file)
|
713
|
+
assert_equal(2, attempts, 'Expected two HTTP calls due to 429 retries')
|
714
|
+
assert_equal('success content', File.read(file))
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
def test_upload_retries_on_busy_server
|
719
|
+
WebMock.disable_net_connect!
|
720
|
+
Dir.mktmpdir do |dir|
|
721
|
+
file = File.join(dir, 'upload.txt')
|
722
|
+
File.write(file, 'test content')
|
723
|
+
attempts = 0
|
724
|
+
stub_request(:put, 'https://example.org:443/file')
|
725
|
+
.to_return do |_request|
|
726
|
+
attempts += 1
|
727
|
+
if attempts < 2
|
728
|
+
{ status: 429, body: 'Too Many Requests' }
|
729
|
+
else
|
730
|
+
{ status: 200, body: 'OK' }
|
731
|
+
end
|
732
|
+
end
|
733
|
+
baza = BazaRb.new('example.org', 443, '000', loog: Loog::NULL, compress: false, timeout: 0.1, pause: 0)
|
734
|
+
baza.send(:upload, baza.send(:home).append('file'), file)
|
735
|
+
assert_equal(2, attempts, 'Expected 2 HTTP calls due to 429 retries')
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
708
739
|
def test_durable_load_from_sinatra
|
709
740
|
WebMock.enable_net_connect!
|
710
741
|
Dir.mktmpdir do |dir|
|