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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f94511fc54301a20314e8d456a708e37a1cea845db41e9e2f88389f574f76e8f
4
- data.tar.gz: 97d8b8027bca5379934eec24aacd006209b3fc0e316f94f90c4ad33c1d64aa05
3
+ metadata.gz: 3925181637ee67621a9013cda972f3de775c644d67b530573814d40ff064f6f1
4
+ data.tar.gz: 0d883da9c8f1cc1c4538d303fc3e864e81f4145e443011c7277dc06673bb448d
5
5
  SHA512:
6
- metadata.gz: 4217832c03755e02d6b2c619282105069f1c9131d690704e2918d2dfeee8343f6511095e27e94a46fb9336063f6470057289befb89714eccc5437a8fd05ff2cb
7
- data.tar.gz: 72fd3aabcf03aef3010bafe9659dd5d54e882dffcad12bf8ab0e79e6dad0f34acd5dcf77db7dfe053c740681359d32141863c72676bad489502c29cafe17b63e
6
+ metadata.gz: 3b21df150b5c2c58efce934266400d589adec2d8fb594a43202801f4ae8050b182feda6b72c5b85a1490a6242483f093fc448323a285c51a0db383b166f4c198
7
+ data.tar.gz: fdf81673a2ac0a524ab0abd614fba9dae23a791dbff7311aed8d77afa001269b9cd571d84f57fde3f5f6cd7b4f018c6a8b8c79ff1eb78c326825aa3941ac3f39
@@ -16,4 +16,4 @@ jobs:
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
18
  - uses: actions/checkout@v4
19
- - uses: crate-ci/typos@v1.34.0
19
+ - uses: crate-ci/typos@v1.35.2
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', '~>2.1', require: false
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.1.0)
34
- loog (> 0)
35
- tago (> 0)
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.13.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.2)
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.12.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.3)
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.8-arm64-darwin)
86
+ nokogiri (1.18.9-arm64-darwin)
87
87
  racc (~> 1.4)
88
- nokogiri (1.18.8-x64-mingw-ucrt)
88
+ nokogiri (1.18.9-x64-mingw-ucrt)
89
89
  racc (~> 1.4)
90
- nokogiri (1.18.8-x86_64-darwin)
90
+ nokogiri (1.18.9-x86_64-darwin)
91
91
  racc (~> 1.4)
92
- nokogiri (1.18.8-x86_64-linux-gnu)
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.8.0)
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.0)
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.1.16)
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.10.0)
126
+ regexp_parser (2.11.0)
127
127
  retries (0.0.5)
128
128
  rexml (3.4.1)
129
- rubocop (1.78.0)
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.45.1, < 2.0)
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.45.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 (2.1.0)
160
+ simplecov-cobertura (3.0.0)
161
161
  rexml
162
162
  simplecov (~> 0.19)
163
- simplecov-html (0.13.1)
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 (~> 2.1)
218
+ simplecov-cobertura (~> 3.0)
219
219
  sinatra (~> 4.1)
220
220
  wait_for (~> 0.1)
221
221
  webmock (~> 3.24)
@@ -13,5 +13,5 @@
13
13
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
14
  # License:: MIT
15
15
  class BazaRb
16
- VERSION = '0.9.11'
16
+ VERSION = '0.10.0'
17
17
  end
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: 3, loog: Loog::NULL, compress: true)
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 < 5
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} and try again...")
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 < 5
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} and try again...")
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
- request.on_body do |data|
806
- slice += data
807
- end
808
- retry_it do
809
- request.run
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 == 302
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
- Typhoeus::Request.put(
886
- uri.to_s,
887
- params
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|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baza.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.11
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko