baza.rb 0.9.10 → 0.9.12
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/Gemfile +1 -1
- data/Gemfile.lock +13 -11
- data/lib/baza-rb/version.rb +1 -1
- data/lib/baza-rb.rb +75 -41
- 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: 70695fd3879e61407e448c32960af00dd5fcf3df08014551073b4e6041a5cc6f
|
4
|
+
data.tar.gz: 6c407fbb83271e68b5da3eba246b35ece2326f63f66ca89d4609ac7ad7be4ce6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80f1abe9dccf135b5cd75d1389c52bb28423014cf588a1ea66738576e8808d104d967a69108f459e590ebee9b2772abca3a419db7c8412f73d0114244d5d3b4e
|
7
|
+
data.tar.gz: 8244c0a1d7db36a251380fb911df2bcebc2ac61a1f9aae52d0cb0ef852160c31761402e8164915665c80be651d685730063f0a680012120bdb57f4d52d0cc7f4
|
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
@@ -36,7 +36,7 @@ GEM
|
|
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.0)
|
40
40
|
backtrace (~> 0.4)
|
41
41
|
decoor (~> 0.0)
|
42
42
|
ellipsized (~> 0.3)
|
@@ -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.1)
|
69
69
|
language_server-protocol (3.17.0.5)
|
70
70
|
lint_roller (1.1.0)
|
71
71
|
logger (1.7.0)
|
@@ -83,13 +83,13 @@ GEM
|
|
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)
|
@@ -126,7 +126,7 @@ GEM
|
|
126
126
|
regexp_parser (2.10.0)
|
127
127
|
retries (0.0.5)
|
128
128
|
rexml (3.4.1)
|
129
|
-
rubocop (1.
|
129
|
+
rubocop (1.79.0)
|
130
130
|
json (~> 2.3)
|
131
131
|
language_server-protocol (~> 3.17.0.2)
|
132
132
|
lint_roller (~> 1.1.0)
|
@@ -134,10 +134,11 @@ 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
|
+
tsort (>= 0.2.0)
|
139
140
|
unicode-display_width (>= 2.4.0, < 4.0)
|
140
|
-
rubocop-ast (1.
|
141
|
+
rubocop-ast (1.46.0)
|
141
142
|
parser (>= 3.3.7.2)
|
142
143
|
prism (~> 1.4)
|
143
144
|
rubocop-minitest (0.38.1)
|
@@ -157,7 +158,7 @@ GEM
|
|
157
158
|
docile (~> 1.1)
|
158
159
|
simplecov-html (~> 0.11)
|
159
160
|
simplecov_json_formatter (~> 0.1)
|
160
|
-
simplecov-cobertura (
|
161
|
+
simplecov-cobertura (3.0.0)
|
161
162
|
rexml
|
162
163
|
simplecov (~> 0.19)
|
163
164
|
simplecov-html (0.13.1)
|
@@ -172,6 +173,7 @@ GEM
|
|
172
173
|
tago (0.1.0)
|
173
174
|
tilt (2.6.1)
|
174
175
|
timeout (0.4.3)
|
176
|
+
tsort (0.2.0)
|
175
177
|
typhoeus (1.4.1)
|
176
178
|
ethon (>= 0.9.0)
|
177
179
|
unicode-display_width (3.1.4)
|
@@ -215,7 +217,7 @@ DEPENDENCIES
|
|
215
217
|
rubocop-performance (~> 1.23)
|
216
218
|
rubocop-rake (~> 0.7)
|
217
219
|
simplecov (~> 0.22)
|
218
|
-
simplecov-cobertura (~>
|
220
|
+
simplecov-cobertura (~> 3.0)
|
219
221
|
sinatra (~> 4.1)
|
220
222
|
wait_for (~> 0.1)
|
221
223
|
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
|
|
@@ -644,19 +646,37 @@ class BazaRb
|
|
644
646
|
with_retries(max_tries: @retries, rescue: TimedOut, &)
|
645
647
|
end
|
646
648
|
|
647
|
-
# Execute a block with retries on 429
|
649
|
+
# Execute a block with retries on 429 status codes.
|
648
650
|
#
|
649
651
|
# @yield The block to execute with retries
|
650
652
|
# @return [Object] The result of the block execution
|
651
653
|
def retry_if_server_busy(&)
|
652
|
-
allowed = [429, 500]
|
653
654
|
attempt = 0
|
654
655
|
loop do
|
655
656
|
ret = yield
|
656
|
-
if
|
657
|
+
if ret.code == 429 && attempt < @retries
|
657
658
|
attempt += 1
|
658
|
-
seconds = 2**attempt
|
659
|
-
@loog.info("
|
659
|
+
seconds = @pause * (2**attempt)
|
660
|
+
@loog.info("Server seems to be busy, will sleep for #{seconds} (attempt no.#{attempt})...")
|
661
|
+
sleep(seconds)
|
662
|
+
next
|
663
|
+
end
|
664
|
+
return ret
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
# Execute a block with retries on 500 status codes.
|
669
|
+
#
|
670
|
+
# @yield The block to execute with retries
|
671
|
+
# @return [Object] The result of the block execution
|
672
|
+
def retry_if_server_failed(&)
|
673
|
+
attempt = 0
|
674
|
+
loop do
|
675
|
+
ret = yield
|
676
|
+
if ret.code >= 500 && attempt < @retries
|
677
|
+
attempt += 1
|
678
|
+
seconds = @pause * (2**attempt)
|
679
|
+
@loog.info("Server seems to be in trouble, will sleep for #{seconds} (attempt no.#{attempt})...")
|
660
680
|
sleep(seconds)
|
661
681
|
next
|
662
682
|
end
|
@@ -721,13 +741,15 @@ class BazaRb
|
|
721
741
|
def get(uri, allowed = [200])
|
722
742
|
retry_it do
|
723
743
|
checked(
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
744
|
+
retry_if_server_failed do
|
745
|
+
retry_if_server_busy do
|
746
|
+
Typhoeus::Request.get(
|
747
|
+
uri.to_s,
|
748
|
+
headers:,
|
749
|
+
connecttimeout: @timeout,
|
750
|
+
timeout: @timeout
|
751
|
+
)
|
752
|
+
end
|
731
753
|
end,
|
732
754
|
allowed
|
733
755
|
)
|
@@ -744,13 +766,15 @@ class BazaRb
|
|
744
766
|
def post(uri, params, allowed = [302])
|
745
767
|
retry_it do
|
746
768
|
checked(
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
769
|
+
retry_if_server_failed do
|
770
|
+
Typhoeus::Request.post(
|
771
|
+
uri.to_s,
|
772
|
+
body: params.merge('_csrf' => csrf),
|
773
|
+
headers:,
|
774
|
+
connecttimeout: @timeout,
|
775
|
+
timeout: @timeout
|
776
|
+
)
|
777
|
+
end,
|
754
778
|
allowed
|
755
779
|
)
|
756
780
|
end
|
@@ -768,25 +792,31 @@ class BazaRb
|
|
768
792
|
chunk = 0
|
769
793
|
elapsed(@loog) do
|
770
794
|
loop do
|
771
|
-
request = Typhoeus::Request.new(
|
772
|
-
uri.to_s,
|
773
|
-
method: :get,
|
774
|
-
headers: headers.merge(
|
775
|
-
'Accept' => '*',
|
776
|
-
'Accept-Encoding' => 'gzip',
|
777
|
-
'Range' => "bytes=#{File.size(file)}-"
|
778
|
-
),
|
779
|
-
connecttimeout: @timeout,
|
780
|
-
timeout: @timeout
|
781
|
-
)
|
782
795
|
slice = ''
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
796
|
+
ret = nil
|
797
|
+
retry_if_server_busy do
|
798
|
+
retry_if_server_failed do
|
799
|
+
slice = ''
|
800
|
+
request = Typhoeus::Request.new(
|
801
|
+
uri.to_s,
|
802
|
+
method: :get,
|
803
|
+
headers: headers.merge(
|
804
|
+
'Accept' => '*',
|
805
|
+
'Accept-Encoding' => 'gzip',
|
806
|
+
'Range' => "bytes=#{File.size(file)}-"
|
807
|
+
),
|
808
|
+
connecttimeout: @timeout,
|
809
|
+
timeout: @timeout
|
810
|
+
)
|
811
|
+
request.on_body do |data|
|
812
|
+
slice += data
|
813
|
+
end
|
814
|
+
retry_it do
|
815
|
+
request.run
|
816
|
+
end
|
817
|
+
ret = request.response
|
818
|
+
end
|
788
819
|
end
|
789
|
-
ret = request.response
|
790
820
|
msg = [
|
791
821
|
"GET #{uri.to_uri.path} #{ret.code}",
|
792
822
|
"#{slice.bytesize} bytes",
|
@@ -860,10 +890,14 @@ class BazaRb
|
|
860
890
|
ret =
|
861
891
|
retry_it do
|
862
892
|
checked(
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
893
|
+
retry_if_server_failed do
|
894
|
+
retry_if_server_busy do
|
895
|
+
Typhoeus::Request.put(
|
896
|
+
uri.to_s,
|
897
|
+
params
|
898
|
+
)
|
899
|
+
end
|
900
|
+
end
|
867
901
|
)
|
868
902
|
end
|
869
903
|
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|
|