baza.rb 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cec6d23dff978b5dcf080a6940a875ee1f9a67eb07b61ee5ee4b8a98348113c4
4
- data.tar.gz: 98eb41907e61acc9beeb0397da3b1ec0c9cbb8a1ebd7c8f57422f8be18947cf4
3
+ metadata.gz: f06c63d179589bfc28c89fb3d60d4df8232fca069fdf1b225c830091765cef74
4
+ data.tar.gz: de1e9b335a7b34f702f3367980400d0667b08e78817ecef533eef0f81a38e1a5
5
5
  SHA512:
6
- metadata.gz: 1df697ec1d35721c3d23e6ef0b05d0d1c7e99b47c959b8150e413b18f5fd131efb9d3ca28bbdff4343ab4f012ce86217f4b1ffc8508c92eec2842633b6bef354
7
- data.tar.gz: 9f74b8782d6a5ad2bfa1f0d8450e1c033cf5c8ad22c2a083f20fb2d96f94a8abbdd572b612a9440edf74f1d40d3b09356c471e2befd85fdd8c020b69884f60f3
6
+ metadata.gz: 80c39feaf4cd305ba697f38225203f7a6917899cdc89a0ecf0735196b9f54691ebcac0b3742659e546e083d7d7e472f54c1d7648c9722ab478968e5b8a3bfcb4
7
+ data.tar.gz: 2f37dce17730366ae52e4a4cdd1e69651038402b2a2ab9e806829c275a9140fa0164bbdc31b550a4d809235615d976bd7705ab00e5e7a9186f29898ebece114b
@@ -28,7 +28,7 @@ name: actionlint
28
28
  - master
29
29
  jobs:
30
30
  actionlint:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - name: Download actionlint
@@ -25,7 +25,7 @@ name: codecov
25
25
  - master
26
26
  jobs:
27
27
  codecov:
28
- runs-on: ubuntu-22.04
28
+ runs-on: ubuntu-24.04
29
29
  steps:
30
30
  - uses: actions/checkout@v4
31
31
  - uses: ruby/setup-ruby@v1
@@ -24,7 +24,7 @@ name: copyrights
24
24
  pull_request:
25
25
  jobs:
26
26
  copyrights:
27
- runs-on: ubuntu-22.04
27
+ runs-on: ubuntu-24.04
28
28
  steps:
29
29
  - uses: actions/checkout@v4
30
30
  - uses: yegor256/copyrights-action@0.0.5
@@ -32,7 +32,7 @@ concurrency:
32
32
  cancel-in-progress: true
33
33
  jobs:
34
34
  markdown-lint:
35
- runs-on: ubuntu-22.04
35
+ runs-on: ubuntu-24.04
36
36
  steps:
37
37
  - uses: actions/checkout@v4
38
38
  - uses: articulate/actions-markdownlint@v1
@@ -28,7 +28,7 @@ name: pdd
28
28
  - master
29
29
  jobs:
30
30
  pdd:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: volodya-lombrozo/pdd-action@master
@@ -24,7 +24,7 @@ name: xcop
24
24
  pull_request:
25
25
  jobs:
26
26
  xcop:
27
- runs-on: ubuntu-22.04
27
+ runs-on: ubuntu-24.04
28
28
  steps:
29
29
  - uses: actions/checkout@v4
30
30
  - uses: g4s8/xcop-action@master
@@ -28,7 +28,7 @@ name: yamllint
28
28
  - master
29
29
  jobs:
30
30
  yamllint:
31
- runs-on: ubuntu-22.04
31
+ runs-on: ubuntu-24.04
32
32
  steps:
33
33
  - uses: actions/checkout@v4
34
34
  - uses: ibiqlik/action-yamllint@v3
data/Gemfile CHANGED
@@ -29,12 +29,12 @@ gem 'minitest-reporters', '1.7.1', require: false
29
29
  gem 'net-ping', '2.0.8', require: false
30
30
  gem 'rake', '13.2.1', require: false
31
31
  gem 'random-port', '>0', require: false
32
- gem 'rspec-rails', '6.1.4', require: false
33
- gem 'rubocop', '1.65.1', require: false
34
- gem 'rubocop-performance', '1.21.1', require: false
35
- gem 'rubocop-rspec', '3.0.4', require: false
32
+ gem 'rspec-rails', '7.0.1', require: false
33
+ gem 'rubocop', '1.66.1', require: false
34
+ gem 'rubocop-performance', '1.22.1', require: false
35
+ gem 'rubocop-rspec', '3.1.0', require: false
36
36
  gem 'simplecov', '0.22.0', require: false
37
37
  gem 'simplecov-cobertura', '2.1.0', require: false
38
38
  gem 'wait_for', '~>0', require: false
39
- gem 'webmock', '3.23.1', require: false
40
- gem 'yard', '0.9.36', require: false
39
+ gem 'webmock', '3.24.0', require: false
40
+ gem 'yard', '0.9.37', require: false
data/Gemfile.lock CHANGED
@@ -3,6 +3,7 @@ PATH
3
3
  specs:
4
4
  baza.rb (0.0.0)
5
5
  backtrace (> 0)
6
+ elapsed (> 0)
6
7
  faraday (> 0)
7
8
  faraday-http-cache (> 0)
8
9
  faraday-multipart (> 0)
@@ -16,9 +17,9 @@ PATH
16
17
  GEM
17
18
  remote: https://rubygems.org/
18
19
  specs:
19
- actionpack (7.2.0)
20
- actionview (= 7.2.0)
21
- activesupport (= 7.2.0)
20
+ actionpack (7.2.1)
21
+ actionview (= 7.2.1)
22
+ activesupport (= 7.2.1)
22
23
  nokogiri (>= 1.8.5)
23
24
  racc
24
25
  rack (>= 2.2.4, < 3.2)
@@ -27,13 +28,13 @@ GEM
27
28
  rails-dom-testing (~> 2.2)
28
29
  rails-html-sanitizer (~> 1.6)
29
30
  useragent (~> 0.16)
30
- actionview (7.2.0)
31
- activesupport (= 7.2.0)
31
+ actionview (7.2.1)
32
+ activesupport (= 7.2.1)
32
33
  builder (~> 3.1)
33
34
  erubi (~> 1.11)
34
35
  rails-dom-testing (~> 2.2)
35
36
  rails-html-sanitizer (~> 1.6)
36
- activesupport (7.2.0)
37
+ activesupport (7.2.1)
37
38
  base64
38
39
  bigdecimal
39
40
  concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -62,6 +63,9 @@ GEM
62
63
  diff-lcs (1.5.1)
63
64
  docile (1.4.1)
64
65
  drb (2.2.1)
66
+ elapsed (0.0.1)
67
+ loog (> 0)
68
+ tago (> 0)
65
69
  erubi (1.13.0)
66
70
  ethon (0.16.0)
67
71
  ffi (>= 1.15.0)
@@ -74,14 +78,15 @@ GEM
74
78
  others (> 0)
75
79
  tago (> 0)
76
80
  yaml (~> 0.3)
77
- faraday (2.10.1)
78
- faraday-net_http (>= 2.0, < 3.2)
81
+ faraday (2.12.0)
82
+ faraday-net_http (>= 2.0, < 3.4)
83
+ json
79
84
  logger
80
85
  faraday-http-cache (2.5.1)
81
86
  faraday (>= 0.8)
82
87
  faraday-multipart (1.0.4)
83
88
  multipart-post (~> 2)
84
- faraday-net_http (3.1.1)
89
+ faraday-net_http (3.3.0)
85
90
  net-http
86
91
  faraday-retry (2.2.1)
87
92
  faraday (~> 2.0)
@@ -90,16 +95,16 @@ GEM
90
95
  ffi (1.17.0-x86_64-darwin)
91
96
  ffi (1.17.0-x86_64-linux-gnu)
92
97
  hashdiff (1.1.1)
93
- i18n (1.14.5)
98
+ i18n (1.14.6)
94
99
  concurrent-ruby (~> 1.0)
95
100
  io-console (0.7.2)
96
- irb (1.14.0)
101
+ irb (1.14.1)
97
102
  rdoc (>= 4.0.0)
98
103
  reline (>= 0.4.2)
99
104
  iri (0.8.0)
100
105
  json (2.7.2)
101
106
  language_server-protocol (3.17.0.3)
102
- logger (1.6.0)
107
+ logger (1.6.1)
103
108
  loofah (2.22.0)
104
109
  crass (~> 1.0.2)
105
110
  nokogiri (>= 1.12.0)
@@ -123,15 +128,15 @@ GEM
123
128
  nokogiri (1.16.7-x86_64-linux)
124
129
  racc (~> 1.4)
125
130
  others (0.0.3)
126
- parallel (1.26.2)
127
- parser (3.3.4.2)
131
+ parallel (1.26.3)
132
+ parser (3.3.5.0)
128
133
  ast (~> 2.4.1)
129
134
  racc
130
135
  psych (5.1.2)
131
136
  stringio
132
137
  public_suffix (6.0.1)
133
138
  racc (1.8.1)
134
- rack (3.1.7)
139
+ rack (3.1.8)
135
140
  rack-session (2.0.0)
136
141
  rack (>= 3.0.0)
137
142
  rack-test (2.1.0)
@@ -146,9 +151,9 @@ GEM
146
151
  rails-html-sanitizer (1.6.0)
147
152
  loofah (~> 2.21)
148
153
  nokogiri (~> 1.14)
149
- railties (7.2.0)
150
- actionpack (= 7.2.0)
151
- activesupport (= 7.2.0)
154
+ railties (7.2.1)
155
+ actionpack (= 7.2.1)
156
+ activesupport (= 7.2.1)
152
157
  irb (~> 1.13)
153
158
  rackup (>= 1.0.0)
154
159
  rake (>= 12.2)
@@ -160,45 +165,43 @@ GEM
160
165
  rdoc (6.7.0)
161
166
  psych (>= 4.0.0)
162
167
  regexp_parser (2.9.2)
163
- reline (0.5.9)
168
+ reline (0.5.10)
164
169
  io-console (~> 0.5)
165
170
  retries (0.0.5)
166
- rexml (3.3.5)
167
- strscan
168
- rspec-core (3.13.0)
171
+ rexml (3.3.8)
172
+ rspec-core (3.13.1)
169
173
  rspec-support (~> 3.13.0)
170
- rspec-expectations (3.13.1)
174
+ rspec-expectations (3.13.3)
171
175
  diff-lcs (>= 1.2.0, < 2.0)
172
176
  rspec-support (~> 3.13.0)
173
- rspec-mocks (3.13.1)
177
+ rspec-mocks (3.13.2)
174
178
  diff-lcs (>= 1.2.0, < 2.0)
175
179
  rspec-support (~> 3.13.0)
176
- rspec-rails (6.1.4)
177
- actionpack (>= 6.1)
178
- activesupport (>= 6.1)
179
- railties (>= 6.1)
180
+ rspec-rails (7.0.1)
181
+ actionpack (>= 7.0)
182
+ activesupport (>= 7.0)
183
+ railties (>= 7.0)
180
184
  rspec-core (~> 3.13)
181
185
  rspec-expectations (~> 3.13)
182
186
  rspec-mocks (~> 3.13)
183
187
  rspec-support (~> 3.13)
184
188
  rspec-support (3.13.1)
185
- rubocop (1.65.1)
189
+ rubocop (1.66.1)
186
190
  json (~> 2.3)
187
191
  language_server-protocol (>= 3.17.0)
188
192
  parallel (~> 1.10)
189
193
  parser (>= 3.3.0.2)
190
194
  rainbow (>= 2.2.2, < 4.0)
191
195
  regexp_parser (>= 2.4, < 3.0)
192
- rexml (>= 3.2.5, < 4.0)
193
- rubocop-ast (>= 1.31.1, < 2.0)
196
+ rubocop-ast (>= 1.32.2, < 2.0)
194
197
  ruby-progressbar (~> 1.7)
195
198
  unicode-display_width (>= 2.4.0, < 3.0)
196
- rubocop-ast (1.32.0)
199
+ rubocop-ast (1.32.3)
197
200
  parser (>= 3.3.1.0)
198
- rubocop-performance (1.21.1)
201
+ rubocop-performance (1.22.1)
199
202
  rubocop (>= 1.48.1, < 2.0)
200
203
  rubocop-ast (>= 1.31.1, < 2.0)
201
- rubocop-rspec (3.0.4)
204
+ rubocop-rspec (3.1.0)
202
205
  rubocop (~> 1.61)
203
206
  ruby-progressbar (1.13.0)
204
207
  securerandom (0.3.1)
@@ -209,28 +212,27 @@ GEM
209
212
  simplecov-cobertura (2.1.0)
210
213
  rexml
211
214
  simplecov (~> 0.19)
212
- simplecov-html (0.12.3)
215
+ simplecov-html (0.13.1)
213
216
  simplecov_json_formatter (0.1.4)
214
217
  stringio (3.1.1)
215
- strscan (3.1.0)
216
218
  tago (0.0.2)
217
- thor (1.3.1)
219
+ thor (1.3.2)
218
220
  typhoeus (1.4.1)
219
221
  ethon (>= 0.9.0)
220
222
  tzinfo (2.0.6)
221
223
  concurrent-ruby (~> 1.0)
222
- unicode-display_width (2.5.0)
223
- uri (0.13.0)
224
+ unicode-display_width (2.6.0)
225
+ uri (0.13.1)
224
226
  useragent (0.16.10)
225
227
  wait_for (0.1.1)
226
- webmock (3.23.1)
228
+ webmock (3.24.0)
227
229
  addressable (>= 2.8.0)
228
230
  crack (>= 0.3.2)
229
231
  hashdiff (>= 0.4.0, < 2.0.0)
230
- webrick (1.8.1)
232
+ webrick (1.8.2)
231
233
  yaml (0.3.0)
232
- yard (0.9.36)
233
- zeitwerk (2.6.17)
234
+ yard (0.9.37)
235
+ zeitwerk (2.7.0)
234
236
 
235
237
  PLATFORMS
236
238
  arm64-darwin-22
@@ -247,15 +249,15 @@ DEPENDENCIES
247
249
  net-ping (= 2.0.8)
248
250
  rake (= 13.2.1)
249
251
  random-port (> 0)
250
- rspec-rails (= 6.1.4)
251
- rubocop (= 1.65.1)
252
- rubocop-performance (= 1.21.1)
253
- rubocop-rspec (= 3.0.4)
252
+ rspec-rails (= 7.0.1)
253
+ rubocop (= 1.66.1)
254
+ rubocop-performance (= 1.22.1)
255
+ rubocop-rspec (= 3.1.0)
254
256
  simplecov (= 0.22.0)
255
257
  simplecov-cobertura (= 2.1.0)
256
258
  wait_for (~> 0)
257
- webmock (= 3.23.1)
258
- yard (= 0.9.36)
259
+ webmock (= 3.24.0)
260
+ yard (= 0.9.37)
259
261
 
260
262
  BUNDLED WITH
261
263
  2.4.22
data/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![Hits-of-Code](https://hitsofcode.com/github/zerocracy/baza.rb)](https://hitsofcode.com/view/github/zerocracy/baza.rb)
11
11
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/zerocracy/baza.rb/blob/master/LICENSE.txt)
12
12
 
13
- It's an clinet for [Zerocracy API](https://www.zerocracy.com), in Ruby.
13
+ It's an client for [Zerocracy API](https://www.zerocracy.com), in Ruby.
14
14
 
15
15
  ## How to contribute
16
16
 
data/baza.rb.gemspec CHANGED
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  s.rdoc_options = ['--charset=UTF-8']
42
42
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
43
43
  s.add_dependency 'backtrace', '>0'
44
+ s.add_dependency 'elapsed', '>0'
44
45
  s.add_dependency 'faraday', '>0'
45
46
  s.add_dependency 'faraday-http-cache', '>0'
46
47
  s.add_dependency 'faraday-multipart', '>0'
@@ -22,9 +22,13 @@
22
22
 
23
23
  # Just a version.
24
24
  #
25
+ # We keep this file separate from the "baza-rb.rb" in order to have an
26
+ # ability to include it from the ".gemspec" script, without including all
27
+ # other packages (thus failing the build).
28
+ #
25
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
26
30
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
27
31
  # License:: MIT
28
32
  class BazaRb
29
- VERSION = '0.0.7'
33
+ VERSION = '0.0.9'
30
34
  end
data/lib/baza-rb.rb CHANGED
@@ -21,6 +21,8 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'base64'
24
+ require 'elapsed'
25
+ require 'fileutils'
24
26
  require 'iri'
25
27
  require 'loog'
26
28
  require 'retries'
@@ -38,7 +40,26 @@ require_relative 'baza-rb/version'
38
40
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
39
41
  # License:: MIT
40
42
  class BazaRb
41
- def initialize(host, port, token, ssl: true, timeout: 30, retries: 3, loog: Loog::NULL, compression: true)
43
+ # When the server failed (503).
44
+ class ServerFailure < StandardError; end
45
+
46
+ # When request timeout.
47
+ class TimedOut < StandardError; end
48
+
49
+ # Unexpected response arrived from the server.
50
+ class BadResponse < StandardError; end
51
+
52
+ # Ctor.
53
+ #
54
+ # @param [String] host Host name
55
+ # @param [Integer] port TCP port
56
+ # @param [String] token Secret token of zerocracy.com
57
+ # @param [Boolean] ssl Should we use SSL?
58
+ # @param [Float] timeout Connect timeout and session timeout, in seconds
59
+ # @param [Integer] retries How many times to retry on connection failure?
60
+ # @param [Loog] loog The logging facility
61
+ # @param [Boolean] compress Set to TRUE if need to use GZIP while pulling and sending
62
+ def initialize(host, port, token, ssl: true, timeout: 30, retries: 3, loog: Loog::NULL, compress: true)
42
63
  @host = host
43
64
  @port = port
44
65
  @ssl = ssl
@@ -46,10 +67,11 @@ class BazaRb
46
67
  @timeout = timeout
47
68
  @loog = loog
48
69
  @retries = retries
49
- @compression = compression
70
+ @compress = compress
50
71
  end
51
72
 
52
73
  # Push factbase to the server.
74
+ #
53
75
  # @param [String] name The name of the job on the server
54
76
  # @param [Bytes] data The data to push to the server (binary)
55
77
  # @param [Array<String>] meta List of metas, possibly empty
@@ -75,11 +97,11 @@ class BazaRb
75
97
  }
76
98
  elapsed(@loog) do
77
99
  ret =
78
- with_retries(max_tries: @retries) do
100
+ with_retries(max_tries: @retries, rescue: TimedOut) do
79
101
  checked(
80
102
  Typhoeus::Request.put(
81
103
  home.append('push').append(name).to_s,
82
- @compression ? zipped(params) : params
104
+ @compress ? zipped(params) : params
83
105
  )
84
106
  )
85
107
  end
@@ -90,6 +112,7 @@ class BazaRb
90
112
  end
91
113
 
92
114
  # Pull factbase from the server.
115
+ #
93
116
  # @param [Integer] id The ID of the job on the server
94
117
  # @return [Bytes] Binary data pulled
95
118
  def pull(id)
@@ -112,7 +135,7 @@ class BazaRb
112
135
  request.on_body do |chunk|
113
136
  f.write(chunk)
114
137
  end
115
- with_retries(max_tries: @retries) do
138
+ with_retries(max_tries: @retries, rescue: TimedOut) do
116
139
  request.run
117
140
  end
118
141
  checked(request.response)
@@ -125,6 +148,7 @@ class BazaRb
125
148
  end
126
149
 
127
150
  # The job with this ID is finished already?
151
+ #
128
152
  # @param [Integer] id The ID of the job on the server
129
153
  # @return [Boolean] TRUE if the job is already finished
130
154
  def finished?(id)
@@ -133,7 +157,7 @@ class BazaRb
133
157
  finished = false
134
158
  elapsed(@loog) do
135
159
  ret =
136
- with_retries(max_tries: @retries) do
160
+ with_retries(max_tries: @retries, rescue: TimedOut) do
137
161
  checked(
138
162
  Typhoeus::Request.get(
139
163
  home.append('finished').append(id).to_s,
@@ -148,6 +172,7 @@ class BazaRb
148
172
  end
149
173
 
150
174
  # Read and return the stdout of the job.
175
+ #
151
176
  # @param [Integer] id The ID of the job on the server
152
177
  # @return [String] The stdout, as a text
153
178
  def stdout(id)
@@ -156,7 +181,7 @@ class BazaRb
156
181
  stdout = ''
157
182
  elapsed(@loog) do
158
183
  ret =
159
- with_retries(max_tries: @retries) do
184
+ with_retries(max_tries: @retries, rescue: TimedOut) do
160
185
  checked(
161
186
  Typhoeus::Request.get(
162
187
  home.append('stdout').append("#{id}.txt").to_s,
@@ -171,6 +196,7 @@ class BazaRb
171
196
  end
172
197
 
173
198
  # Read and return the exit code of the job.
199
+ #
174
200
  # @param [Integer] id The ID of the job on the server
175
201
  # @return [Integer] The exit code
176
202
  def exit_code(id)
@@ -179,7 +205,7 @@ class BazaRb
179
205
  code = 0
180
206
  elapsed(@loog) do
181
207
  ret =
182
- with_retries(max_tries: @retries) do
208
+ with_retries(max_tries: @retries, rescue: TimedOut) do
183
209
  checked(
184
210
  Typhoeus::Request.get(
185
211
  home.append('exit').append("#{id}.txt").to_s,
@@ -194,6 +220,7 @@ class BazaRb
194
220
  end
195
221
 
196
222
  # Read and return the verification verdict of the job.
223
+ #
197
224
  # @param [Integer] id The ID of the job on the server
198
225
  # @return [String] The verdict
199
226
  def verified(id)
@@ -202,7 +229,7 @@ class BazaRb
202
229
  verdict = 0
203
230
  elapsed(@loog) do
204
231
  ret =
205
- with_retries(max_tries: @retries) do
232
+ with_retries(max_tries: @retries, rescue: TimedOut) do
206
233
  checked(
207
234
  Typhoeus::Request.get(
208
235
  home.append('jobs').append(id).append('verified.txt').to_s,
@@ -217,6 +244,7 @@ class BazaRb
217
244
  end
218
245
 
219
246
  # Lock the name.
247
+ #
220
248
  # @param [String] name The name of the job on the server
221
249
  # @param [String] owner The owner of the lock (any string)
222
250
  def lock(name, owner)
@@ -224,7 +252,7 @@ class BazaRb
224
252
  raise 'The "name" of the job may not be empty' if name.empty?
225
253
  raise 'The "owner" of the lock is nil' if owner.nil?
226
254
  elapsed(@loog) do
227
- with_retries(max_tries: @retries) do
255
+ with_retries(max_tries: @retries, rescue: TimedOut) do
228
256
  checked(
229
257
  Typhoeus::Request.get(
230
258
  home.append('lock').append(name).add(owner:).to_s,
@@ -238,6 +266,7 @@ class BazaRb
238
266
  end
239
267
 
240
268
  # Unlock the name.
269
+ #
241
270
  # @param [String] name The name of the job on the server
242
271
  # @param [String] owner The owner of the lock (any string)
243
272
  def unlock(name, owner)
@@ -245,7 +274,7 @@ class BazaRb
245
274
  raise 'The "name" of the job may not be empty' if name.empty?
246
275
  raise 'The "owner" of the lock is nil' if owner.nil?
247
276
  elapsed(@loog) do
248
- with_retries(max_tries: @retries) do
277
+ with_retries(max_tries: @retries, rescue: TimedOut) do
249
278
  checked(
250
279
  Typhoeus::Request.get(
251
280
  home.append('unlock').append(name).add(owner:).to_s,
@@ -259,6 +288,7 @@ class BazaRb
259
288
  end
260
289
 
261
290
  # Get the ID of the job by the name.
291
+ #
262
292
  # @param [String] name The name of the job on the server
263
293
  # @return [Integer] The ID of the job on the server
264
294
  def recent(name)
@@ -267,7 +297,7 @@ class BazaRb
267
297
  job = 0
268
298
  elapsed(@loog) do
269
299
  ret =
270
- with_retries(max_tries: @retries) do
300
+ with_retries(max_tries: @retries, rescue: TimedOut) do
271
301
  checked(
272
302
  Typhoeus::Request.get(
273
303
  home.append('recent').append("#{name}.txt").to_s,
@@ -282,6 +312,7 @@ class BazaRb
282
312
  end
283
313
 
284
314
  # Check whether the name of the job exists on the server.
315
+ #
285
316
  # @param [String] name The name of the job on the server
286
317
  # @return [Boolean] TRUE if such name exists
287
318
  def name_exists?(name)
@@ -290,7 +321,7 @@ class BazaRb
290
321
  exists = 0
291
322
  elapsed(@loog) do
292
323
  ret =
293
- with_retries(max_tries: @retries) do
324
+ with_retries(max_tries: @retries, rescue: TimedOut) do
294
325
  checked(
295
326
  Typhoeus::Request.get(
296
327
  home.append('exists').append(name).to_s,
@@ -305,6 +336,7 @@ class BazaRb
305
336
  end
306
337
 
307
338
  # Place a single durable.
339
+ #
308
340
  # @param [String] jname The name of the job on the server
309
341
  # @param [String] file The file name
310
342
  def durable_place(jname, file)
@@ -315,7 +347,7 @@ class BazaRb
315
347
  id = nil
316
348
  elapsed(@loog) do
317
349
  ret =
318
- with_retries(max_tries: @retries) do
350
+ with_retries(max_tries: @retries, rescue: TimedOut) do
319
351
  checked(
320
352
  Typhoeus::Request.post(
321
353
  home.append('durables').append('place').to_s,
@@ -338,6 +370,7 @@ class BazaRb
338
370
  end
339
371
 
340
372
  # Save a single durable from local file to server.
373
+ #
341
374
  # @param [Integer] id The ID of the durable
342
375
  # @param [String] file The file to upload
343
376
  def durable_save(id, file)
@@ -346,7 +379,7 @@ class BazaRb
346
379
  raise 'The "file" of the durable is nil' if file.nil?
347
380
  raise "The file '#{file}' is absent" unless File.exist?(file)
348
381
  elapsed(@loog) do
349
- with_retries(max_tries: @retries) do
382
+ with_retries(max_tries: @retries, rescue: TimedOut) do
350
383
  checked(
351
384
  Typhoeus::Request.put(
352
385
  home.append('durables').append(id).to_s,
@@ -362,6 +395,7 @@ class BazaRb
362
395
  end
363
396
 
364
397
  # Load a single durable from server to local file.
398
+ #
365
399
  # @param [Integer] id The ID of the durable
366
400
  # @param [String] file The file to upload
367
401
  def durable_load(id, file)
@@ -383,7 +417,7 @@ class BazaRb
383
417
  request.on_body do |chunk|
384
418
  f.write(chunk)
385
419
  end
386
- with_retries(max_tries: @retries) do
420
+ with_retries(max_tries: @retries, rescue: TimedOut) do
387
421
  request.run
388
422
  end
389
423
  checked(request.response)
@@ -393,6 +427,7 @@ class BazaRb
393
427
  end
394
428
 
395
429
  # Lock a single durable.
430
+ #
396
431
  # @param [Integer] id The ID of the durable
397
432
  # @param [String] owner The owner of the lock
398
433
  def durable_lock(id, owner)
@@ -401,7 +436,7 @@ class BazaRb
401
436
  raise 'The "owner" of the lock is nil' if owner.nil?
402
437
  raise 'The "owner" of the lock may not be empty' if owner.empty?
403
438
  elapsed(@loog) do
404
- with_retries(max_tries: @retries) do
439
+ with_retries(max_tries: @retries, rescue: TimedOut) do
405
440
  checked(
406
441
  Typhoeus::Request.get(
407
442
  home.append('durables').append(id).append('lock').add(owner:).to_s,
@@ -415,6 +450,7 @@ class BazaRb
415
450
  end
416
451
 
417
452
  # Unlock a single durable.
453
+ #
418
454
  # @param [Integer] id The ID of the durable
419
455
  # @param [String] owner The owner of the lock
420
456
  def durable_unlock(id, owner)
@@ -423,7 +459,7 @@ class BazaRb
423
459
  raise 'The "owner" of the lock is nil' if owner.nil?
424
460
  raise 'The "owner" of the lock may not be empty' if owner.empty?
425
461
  elapsed(@loog) do
426
- with_retries(max_tries: @retries) do
462
+ with_retries(max_tries: @retries, rescue: TimedOut) do
427
463
  checked(
428
464
  Typhoeus::Request.get(
429
465
  home.append('durables').append(id).append('unlock').add(owner:).to_s,
@@ -436,6 +472,104 @@ class BazaRb
436
472
  end
437
473
  end
438
474
 
475
+ # Pop job from the server.
476
+ #
477
+ # @param [String] owner Who is acting (could be any text)
478
+ # @param [String] zip The path to ZIP archive to take
479
+ # @return [Boolean] TRUE if job taken, otherwise false
480
+ def pop(owner, zip)
481
+ raise 'The "zip" of the job is nil' if zip.nil?
482
+ success = false
483
+ FileUtils.rm_f(zip)
484
+ elapsed(@loog) do
485
+ File.open(zip, 'wb') do |f|
486
+ request = Typhoeus::Request.new(
487
+ home.append('pop').add(owner:).to_s,
488
+ method: :get,
489
+ headers: headers.merge(
490
+ 'Accept' => 'application/octet-stream'
491
+ ),
492
+ connecttimeout: @timeout,
493
+ timeout: @timeout
494
+ )
495
+ request.on_body do |chunk|
496
+ f.write(chunk)
497
+ end
498
+ with_retries(max_tries: @retries, rescue: TimedOut) do
499
+ request.run
500
+ end
501
+ ret = request.response
502
+ checked(ret, [200, 204])
503
+ success = ret.code == 200
504
+ end
505
+ unless success
506
+ FileUtils.rm_f(zip)
507
+ throw :"Nothing to pop at #{@host}"
508
+ end
509
+ throw :"Popped #{File.size(zip)} bytes in ZIP archive at #{@host}"
510
+ end
511
+ success
512
+ end
513
+
514
+ # Submit a ZIP archvie to finish a job.
515
+ #
516
+ # @param [Integer] id The ID of the job on the server
517
+ # @param [String] zip The path to the ZIP file with the content of the archive
518
+ def finish(id, zip)
519
+ raise 'The "id" of the job is nil' if id.nil?
520
+ raise 'The "id" of the job must be an integer' unless id.is_a?(Integer)
521
+ raise 'The "zip" of the job is nil' if zip.nil?
522
+ raise "The 'zip' file is absent: #{zip}" unless File.exist?(zip)
523
+ elapsed(@loog) do
524
+ with_retries(max_tries: @retries, rescue: TimedOut) do
525
+ checked(
526
+ Typhoeus::Request.put(
527
+ home.append('finish').add(id:).to_s,
528
+ connecttimeout: @timeout,
529
+ timeout: @timeout,
530
+ body: File.binread(zip),
531
+ headers: headers.merge(
532
+ 'Content-Type' => 'application/octet-stream',
533
+ 'Content-Length' => File.size(zip)
534
+ )
535
+ )
536
+ )
537
+ end
538
+ throw :"Pushed #{File.size(zip)} bytes to #{@host}, finished job ##{id}"
539
+ end
540
+ end
541
+
542
+ # Enter a valve.
543
+ #
544
+ # @param [String] name Name of the job
545
+ # @param [String] badge Unique badge of the valve
546
+ # @param [String] why The reason
547
+ # @param [nil|Integer] job The ID of the job
548
+ # @return [String] The result just calculated or retrieved
549
+ def enter(name, badge, why, job)
550
+ elapsed(@loog, intro: "Entered valve #{badge} to #{name}") do
551
+ with_retries(max_tries: @retries, rescue: TimedOut) do
552
+ ret = checked(
553
+ Typhoeus::Request.get(
554
+ home.append('valves').append('result').add(badge:).to_s,
555
+ headers:
556
+ ),
557
+ [200, 204]
558
+ )
559
+ return ret.body if ret.code == 200
560
+ r = yield
561
+ uri = home.append('valves').append('add')
562
+ .add(name:)
563
+ .add(badge:)
564
+ .add(why:)
565
+ .add(result: r.to_s)
566
+ uri = uri.add(job:) unless job.nil?
567
+ checked(Typhoeus::Request.post(uri.to_s, headers:), 302)
568
+ r
569
+ end
570
+ end
571
+ end
572
+
439
573
  private
440
574
 
441
575
  def headers
@@ -460,17 +594,6 @@ class BazaRb
460
594
  params.merge(body:, headers:)
461
595
  end
462
596
 
463
- def elapsed(loog)
464
- start = Time.now
465
- begin
466
- yield
467
- rescue UncaughtThrowError => e
468
- tag = e.tag
469
- throw e unless tag.is_a?(Symbol)
470
- loog.info("#{tag} in #{start.ago}")
471
- end
472
- end
473
-
474
597
  def gzip(data)
475
598
  ''.dup.tap do |result|
476
599
  io = StringIO.new(result)
@@ -487,14 +610,19 @@ class BazaRb
487
610
  .scheme(@ssl ? 'https' : 'http')
488
611
  end
489
612
 
613
+ # Check the HTTP response and return it.
614
+ #
615
+ # @param [Typhoeus::Response] ret The response
616
+ # @param [Array<Integer>] allowed List of acceptable HTTP codes
617
+ # @return [Typhoeus::Response] The same response
490
618
  def checked(ret, allowed = [200])
491
619
  allowed = [allowed] unless allowed.is_a?(Array)
492
620
  mtd = (ret.request.original_options[:method] || '???').upcase
493
621
  url = ret.effective_url
494
622
  if ret.return_code == :operation_timedout
495
623
  msg = "#{mtd} #{url} timed out in #{ret.total_time}s"
496
- @loog.debug(msg)
497
- raise msg
624
+ @loog.error(msg)
625
+ raise TimedOut, msg
498
626
  end
499
627
  log = "#{mtd} #{url} -> #{ret.code} (#{format('%0.2f', ret.total_time)}s)"
500
628
  if allowed.include?(ret.code)
@@ -524,6 +652,7 @@ class BazaRb
524
652
  when 0
525
653
  msg += ', most likely an internal error'
526
654
  end
527
- raise msg
655
+ @loog.error(msg)
656
+ raise ServerFailure, msg
528
657
  end
529
658
  end
data/test/test_baza-rb.rb CHANGED
@@ -70,7 +70,7 @@ class TestBazaRb < Minitest::Test
70
70
  fb = Factbase.new
71
71
  fb.insert.foo = 'test-' * 10_000
72
72
  fb.insert
73
- baza = BazaRb.new(HOST, PORT, TOKEN, compression: false)
73
+ baza = BazaRb.new(HOST, PORT, TOKEN, compress: false)
74
74
  assert(baza.push(fake_name, fb.export, []).positive?)
75
75
  end
76
76
 
@@ -89,6 +89,16 @@ class TestBazaRb < Minitest::Test
89
89
  end
90
90
  end
91
91
 
92
+ def test_live_enter_valve
93
+ WebMock.enable_net_connect!
94
+ skip unless we_are_online
95
+ r = 'something'
96
+ n = fake_name
97
+ badge = fake_name
98
+ assert_equal(r, LIVE.enter(n, badge, 'no reason', nil) { r })
99
+ assert_equal(r, LIVE.enter(n, badge, 'no reason', nil) { nil })
100
+ end
101
+
92
102
  def test_durable_place
93
103
  WebMock.disable_net_connect!
94
104
  stub_request(:post, 'https://example.org/durables/place').to_return(
@@ -112,6 +122,23 @@ class TestBazaRb < Minitest::Test
112
122
  )
113
123
  end
114
124
 
125
+ def test_simple_pop
126
+ WebMock.disable_net_connect!
127
+ stub_request(:get, 'https://example.org/pop?owner=me').to_return(status: 204)
128
+ Tempfile.open do |zip|
129
+ assert(!BazaRb.new('example.org', 443, '000').pop('me', zip.path))
130
+ assert(!File.exist?(zip.path))
131
+ end
132
+ end
133
+
134
+ def test_simple_finish
135
+ WebMock.disable_net_connect!
136
+ stub_request(:put, 'https://example.org/finish?id=42').to_return(status: 200)
137
+ Tempfile.open do |zip|
138
+ BazaRb.new('example.org', 443, '000').finish(42, zip.path)
139
+ end
140
+ end
141
+
115
142
  def test_simple_recent_check
116
143
  WebMock.disable_net_connect!
117
144
  stub_request(:get, 'https://example.org/recent/simple.txt')
@@ -163,7 +190,20 @@ class TestBazaRb < Minitest::Test
163
190
  )
164
191
  end
165
192
 
193
+ def test_push_with_server_failure
194
+ WebMock.disable_net_connect!
195
+ stub_request(:put, 'https://example.org/push/foo')
196
+ .to_return(status: 503, body: 'oops', headers: { 'X-Zerocracy-Failure': 'the failure' })
197
+ .to_raise('why second time?')
198
+ e = assert_raises { BazaRb.new('example.org', 443, '000').push('foo', 'data', []) }
199
+ [
200
+ 'Invalid response code #503',
201
+ '"the failure"'
202
+ ].each { |t| assert(e.message.include?(t), "Can't find '#{t}' in #{e.message.inspect}") }
203
+ end
204
+
166
205
  def test_real_http
206
+ WebMock.enable_net_connect!
167
207
  req =
168
208
  with_http_server(200, 'yes') do |baza|
169
209
  baza.name_exists?('simple')
@@ -172,6 +212,7 @@ class TestBazaRb < Minitest::Test
172
212
  end
173
213
 
174
214
  def test_push_with_meta
215
+ WebMock.enable_net_connect!
175
216
  req =
176
217
  with_http_server(200, 'yes') do |baza|
177
218
  baza.push('simple', 'hello, world!', ['boom!', 'хей!'])
@@ -180,6 +221,7 @@ class TestBazaRb < Minitest::Test
180
221
  end
181
222
 
182
223
  def test_push_with_big_meta
224
+ WebMock.enable_net_connect!
183
225
  req =
184
226
  with_http_server(200, 'yes') do |baza|
185
227
  baza.push(
@@ -196,6 +238,7 @@ class TestBazaRb < Minitest::Test
196
238
  end
197
239
 
198
240
  def test_push_compressed_content
241
+ WebMock.enable_net_connect!
199
242
  req =
200
243
  with_http_server(200, 'yes') do |baza|
201
244
  baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
@@ -207,8 +250,9 @@ class TestBazaRb < Minitest::Test
207
250
  end
208
251
 
209
252
  def test_push_compression_disabled
253
+ WebMock.enable_net_connect!
210
254
  req =
211
- with_http_server(200, 'yes', compression: false) do |baza|
255
+ with_http_server(200, 'yes', compress: false) do |baza|
212
256
  baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
213
257
  end
214
258
  assert_equal('application/octet-stream', req.content_type)
@@ -263,7 +307,7 @@ class TestBazaRb < Minitest::Test
263
307
  end
264
308
 
265
309
  def fake_name
266
- "fake-#{SecureRandom.hex(8)}"
310
+ "fake#{SecureRandom.hex(8)}"
267
311
  end
268
312
 
269
313
  def we_are_online
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baza.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-18 00:00:00.000000000 Z
11
+ date: 2024-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: elapsed
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: faraday
29
43
  requirement: !ruby/object:Gem::Requirement