Class: BazaRb
- Inherits:
-
Object
- Object
- BazaRb
- Defined in:
- lib/baza-rb.rb,
lib/baza-rb/version.rb
Overview
Just a version.
We keep this file separate from the “baza-rb.rb” in order to have an ability to include it from the “.gemspec” script, without including all other packages (thus failing the build).
- Author
-
Yegor Bugayenko (yegor256@gmail.com)
- Copyright
-
Copyright © 2024-2026 Yegor Bugayenko
- License
-
MIT
Defined Under Namespace
Classes: BadCompression, BadResponse, ConnectionFailed, Fake, ServerFailure, TimedOut
Constant Summary collapse
- DEFAULT_CHUNK_SIZE =
How big are the chunks we send, by default, in bytes. Numbers larger than 1Mb may lead to problems with the server, since sending time will be too long and the server may drop connections. Better keep it as is: 1Mb.
1_000_000- VERSION =
'0.14.4'
Instance Method Summary collapse
-
#balance ⇒ Float
Get current balance of the authenticated user.
-
#csrf ⇒ String
Get CSRF token from the server for authenticated requests.
-
#durable_find(pname, file) ⇒ Integer?
Find a durable by job name and file name.
-
#durable_load(id, file) ⇒ Object
Load a single durable from server to local file.
-
#durable_lock(id, owner) ⇒ Object
Lock a single durable.
-
#durable_place(pname, file) ⇒ Integer
Place a single durable file on the server.
-
#durable_save(id, file, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object
Save a single durable from local file to server.
-
#durable_unlock(id, owner) ⇒ Object
Unlock a single durable.
-
#enter(pname, badge, why, job) { ... } ⇒ String
Enter a valve to cache or retrieve a computation result.
-
#exit_code(id) ⇒ Integer
Read and return the exit code of the job.
-
#fee(tab, amount, summary, job) ⇒ Integer
Pay a fee associated with a job.
-
#finished?(id) ⇒ Boolean
Check if the job with this ID is finished already.
-
#initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true) ⇒ BazaRb
constructor
Initialize a new Zerocracy API client.
-
#lock(pname, owner) ⇒ Object
Lock the name.
-
#name_exists?(pname) ⇒ Boolean
Check whether the name of the job exists on the server.
-
#pull(id) ⇒ String
Pull factbase from the server for a specific job.
-
#push(pname, data, meta, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object
Push factbase to the server to create a new job.
-
#recent(name) ⇒ Integer
Get the ID of the job by the name.
-
#stdout(id) ⇒ String
Read and return the stdout of the job.
-
#transfer(recipient, amount, summary, job: nil) ⇒ Integer
Transfer funds to another user.
-
#unlock(pname, owner) ⇒ Object
Unlock the name.
-
#verified(id) ⇒ String
Read and return the verification verdict of the job.
-
#whoami ⇒ String
Get GitHub login name of the logged in user.
Constructor Details
#initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true) ⇒ BazaRb
Initialize a new Zerocracy API client.
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/baza-rb.rb', line 69 def initialize(host, port, token, ssl: true, timeout: 30, retries: 5, pause: 1, loog: Loog::NULL, compress: true) @host = host @port = port @ssl = ssl @token = token @timeout = timeout @loog = loog @retries = retries @pause = pause @compress = compress end |
Instance Method Details
#balance ⇒ Float
Get current balance of the authenticated user.
99 100 101 102 103 104 105 106 107 |
# File 'lib/baza-rb.rb', line 99 def balance z = nil elapsed(@loog, level: Logger::INFO) do ret = get(home.append('account').append('balance')) z = ret.body.to_f throw :"The balance is Ƶ#{z}, at #{@host}" end z end |
#csrf ⇒ String
Get CSRF token from the server for authenticated requests.
The CSRF token is required for POST requests to prevent cross-site request forgery attacks.
535 536 537 538 539 540 541 542 |
# File 'lib/baza-rb.rb', line 535 def csrf token = nil elapsed(@loog, level: Logger::INFO) do token = get(home.append('csrf')).body throw :"CSRF token retrieved (#{token.length} chars)" end token end |
#durable_find(pname, file) ⇒ Integer?
Find a durable by job name and file name.
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/baza-rb.rb', line 412 def durable_find(pname, file) raise 'The "pname" is nil' if pname.nil? raise 'The "pname" may not be empty' if pname.empty? raise 'The "file" is nil' if file.nil? raise 'The "file" may not be empty' if file.empty? id = nil elapsed(@loog, level: Logger::INFO) do ret = get(home.append('durable-find').add(file:, pname:), [200, 404]) if ret.code == 200 id = ret.body.to_i throw :"Found durable ##{id} for job \"#{pname}\" file \"#{file}\" at #{@host}" else throw :"Durable not found for job \"#{pname}\" file \"#{file}\" at #{@host}" end end id end |
#durable_load(id, file) ⇒ Object
Load a single durable from server to local file.
356 357 358 359 360 361 362 363 364 365 |
# File 'lib/baza-rb.rb', line 356 def durable_load(id, file) raise 'The ID of the durable is nil' if id.nil? raise 'The ID of the durable must be an Integer' unless id.is_a?(Integer) raise 'The ID of the durable must be a positive integer' unless id.positive? raise 'The "file" of the durable is nil' if file.nil? elapsed(@loog, level: Logger::INFO) do download(home.append('durables').append(id), file) throw :"Durable ##{id} loaded #{File.size(file)} bytes from #{@host}" end end |
#durable_lock(id, owner) ⇒ Object
Lock a single durable.
372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'lib/baza-rb.rb', line 372 def durable_lock(id, owner) raise 'The ID of the durable is nil' if id.nil? raise 'The ID of the durable must be an Integer' unless id.is_a?(Integer) raise 'The ID of the durable must be a positive integer' unless id.positive? raise 'The "owner" of the lock is nil' if owner.nil? raise 'The "owner" of the lock may not be empty' if owner.empty? elapsed(@loog, level: Logger::INFO) do post( home.append('durables').append(id).append('lock'), { 'owner' => owner } ) throw :"Durable ##{id} locked at #{@host}" end end |
#durable_place(pname, file) ⇒ Integer
Place a single durable file on the server.
The file provided will only be uploaded to the server if the durable is currently absent. If the durable is present, the file will be ignored. It is expected to use only small placeholder files, not real data.
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/baza-rb.rb', line 309 def durable_place(pname, file) raise 'The "pname" of the durable is nil' if pname.nil? raise 'The "pname" of the durable may not be empty' if pname.empty? raise 'The "file" of the durable is nil' if file.nil? raise "The file '#{file}' is absent" unless File.exist?(file) if File.size(file) > 1024 raise "The file '#{file}' is too big (#{File.size(file)} bytes) for durable_place(), use durable_save() instead" end id = nil elapsed(@loog, level: Logger::INFO) do ret = post( home.append('durable-place'), { 'pname' => pname, 'file' => File.basename(file), 'zip' => File.open(file, 'rb') } ) id = ret.headers['X-Zerocracy-DurableId'].to_i throw :"Durable ##{id} (#{file}, #{File.size(file)} bytes) placed for job \"#{pname}\" at #{@host}" end id end |
#durable_save(id, file, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object
Save a single durable from local file to server.
339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/baza-rb.rb', line 339 def durable_save(id, file, chunk_size: DEFAULT_CHUNK_SIZE) raise 'The ID of the durable is nil' if id.nil? raise 'The ID of the durable must be an Integer' unless id.is_a?(Integer) raise 'The ID of the durable must be a positive integer' unless id.positive? raise 'The "file" of the durable is nil' if file.nil? raise "The file '#{file}' is absent" unless File.exist?(file) elapsed(@loog, level: Logger::INFO) do upload(home.append('durables').append(id), file, chunk_size:) throw :"Durable ##{id} saved #{File.size(file)} bytes to #{@host}" end end |
#durable_unlock(id, owner) ⇒ Object
Unlock a single durable.
392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/baza-rb.rb', line 392 def durable_unlock(id, owner) raise 'The ID of the durable is nil' if id.nil? raise 'The ID of the durable must be an Integer' unless id.is_a?(Integer) raise 'The ID of the durable must be a positive integer' unless id.positive? raise 'The "owner" of the lock is nil' if owner.nil? raise 'The "owner" of the lock may not be empty' if owner.empty? elapsed(@loog, level: Logger::INFO) do post( home.append('durables').append(id).append('unlock'), { 'owner' => owner } ) throw :"Durable ##{id} unlocked at #{@host}" end end |
#enter(pname, badge, why, job) { ... } ⇒ String
Enter a valve to cache or retrieve a computation result.
Valves prevent duplicate computations by caching results. If a result for the given badge already exists, it’s returned. Otherwise, the block is executed and its result is cached.
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/baza-rb.rb', line 506 def enter(pname, badge, why, job) elapsed(@loog, good: "Entered valve #{badge} to #{pname}") do retry_it do ret = get(home.append('result').add(badge:), [200, 204]) return ret.body if ret.code == 200 r = yield uri = home.append('valves') uri = uri.add(job:) unless job.nil? post( uri, { 'badge' => badge, 'pname' => pname, 'result' => r.to_s, 'why' => why } ) r end end end |
#exit_code(id) ⇒ Integer
Read and return the exit code of the job.
195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/baza-rb.rb', line 195 def exit_code(id) raise 'The ID of the job is nil' if id.nil? raise 'The ID of the job must be a positive integer' unless id.positive? code = 0 elapsed(@loog, level: Logger::INFO) do ret = get(home.append('exit').append("#{id}.txt")) code = ret.body.to_i throw :"The exit code of the job ##{id} is #{code}" end code end |
#fee(tab, amount, summary, job) ⇒ Integer
Pay a fee associated with a job.
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/baza-rb.rb', line 469 def fee(tab, amount, summary, job) raise 'The "tab" is nil' if tab.nil? raise 'The "amount" is nil' if amount.nil? raise 'The "amount" must be Float' unless amount.is_a?(Float) raise 'The "job" is nil' if job.nil? raise 'The "job" must be Integer' unless job.is_a?(Integer) raise 'The "summary" is nil' if summary.nil? id = nil elapsed(@loog, level: Logger::INFO) do ret = post( home.append('account').append('fee'), { 'amount' => format('%0.6f', amount), 'job' => job.to_s, 'summary' => summary, 'tab' => tab } ) id = ret.headers['X-Zerocracy-ReceiptId'].to_i throw :"Fee Ƶ#{format('%0.6f', amount)} paid at #{@host}" end id end |
#finished?(id) ⇒ Boolean
Check if the job with this ID is finished already.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/baza-rb.rb', line 161 def finished?(id) raise 'The ID of the job is nil' if id.nil? raise 'The ID of the job must be a positive integer' unless id.positive? fin = false elapsed(@loog, level: Logger::INFO) do ret = get(home.append('finished').append(id)) fin = ret.body == 'yes' throw :"The job ##{id} is #{'not yet ' unless fin}finished at #{@host}#{" (#{ret.body.inspect})" unless fin}" end fin end |
#lock(pname, owner) ⇒ Object
Lock the name.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/baza-rb.rb', line 230 def lock(pname, owner) raise 'The "pname" of the product is nil' if pname.nil? raise 'The "pname" of the product may not be empty' if pname.empty? raise 'The "owner" of the lock is nil' if owner.nil? raise 'The "owner" of the lock may not be empty' if owner.empty? elapsed(@loog, level: Logger::INFO) do ret = post( home.append('lock').append(pname), { 'owner' => owner }, [302, 409] ) throw :"Product name #{pname.inspect} locked at #{@host}" if ret.code == 302 raise "Failed to lock #{pname.inspect} product at #{@host}, it's already locked" end end |
#name_exists?(pname) ⇒ Boolean
Check whether the name of the job exists on the server.
286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/baza-rb.rb', line 286 def name_exists?(pname) raise 'The "pname" of the product is nil' if pname.nil? raise 'The "pname" of the product may not be empty' if pname.empty? exists = false elapsed(@loog, level: Logger::INFO) do ret = get(home.append('exists').append(pname)) exists = ret.body == 'yes' throw :"The name #{pname.inspect} #{exists ? 'exists' : "doesn't exist"} at #{@host}" end exists end |
#pull(id) ⇒ String
Pull factbase from the server for a specific job.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/baza-rb.rb', line 142 def pull(id) raise 'The ID of the job is nil' if id.nil? raise 'The ID of the job must be a positive integer' unless id.positive? data = '' elapsed(@loog, level: Logger::INFO) do Tempfile.open do |file| download(home.append('pull').append("#{id}.fb"), file.path) data = File.binread(file) throw :"Pulled #{data.bytesize} bytes of job ##{id} factbase at #{@host}" end end data end |
#push(pname, data, meta, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Object
Push factbase to the server to create a new job.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/baza-rb.rb', line 116 def push(pname, data, , chunk_size: DEFAULT_CHUNK_SIZE) raise 'The "name" of the job is nil' if pname.nil? raise 'The "name" of the job may not be empty' if pname.empty? raise 'The "data" of the job is nil' if data.nil? raise 'The "meta" of the job is nil' if .nil? elapsed(@loog, level: Logger::INFO) do Tempfile.open do |file| File.binwrite(file.path, data) upload( home.append('push').append(pname), file.path, headers.merge( 'X-Zerocracy-Meta' => .map { |v| Base64.encode64(v).delete("\n") }.join(' ') ), chunk_size: ) end throw :"Pushed #{data.bytesize} bytes to #{@host}" end end |
#recent(name) ⇒ Integer
Get the ID of the job by the name.
270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/baza-rb.rb', line 270 def recent(name) raise 'The "name" of the job is nil' if name.nil? raise 'The "name" of the job may not be empty' if name.empty? job = nil elapsed(@loog, level: Logger::INFO) do ret = get(home.append('recent').append("#{name}.txt")) job = ret.body.to_i throw :"The recent \"#{name}\" job's ID is ##{job} at #{@host}" end job end |
#stdout(id) ⇒ String
Read and return the stdout of the job.
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/baza-rb.rb', line 178 def stdout(id) raise 'The ID of the job is nil' if id.nil? raise 'The ID of the job must be a positive integer' unless id.positive? stdout = '' elapsed(@loog, level: Logger::INFO) do ret = get(home.append('stdout').append("#{id}.txt")) stdout = ret.body throw :"The stdout of the job ##{id} has #{stdout.split("\n").count} lines" end stdout end |
#transfer(recipient, amount, summary, job: nil) ⇒ Integer
Transfer funds to another user.
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 |
# File 'lib/baza-rb.rb', line 438 def transfer(recipient, amount, summary, job: nil) raise 'The "recipient" is nil' if recipient.nil? raise 'The "amount" is nil' if amount.nil? raise 'The "amount" must be Float' unless amount.is_a?(Float) raise 'The "summary" is nil' if summary.nil? id = nil body = { 'human' => recipient, 'amount' => format('%0.6f', amount), 'summary' => summary } body['job'] = job unless job.nil? elapsed(@loog, level: Logger::INFO) do ret = post( home.append('account').append('transfer'), body ) id = ret.headers['X-Zerocracy-ReceiptId'].to_i throw :"Transferred Ƶ#{format('%0.6f', amount)} to @#{recipient} at #{@host}" end id end |
#unlock(pname, owner) ⇒ Object
Unlock the name.
251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/baza-rb.rb', line 251 def unlock(pname, owner) raise 'The "pname" of the job is nil' if pname.nil? raise 'The "pname" of the job may not be empty' if pname.empty? raise 'The "owner" of the lock is nil' if owner.nil? raise 'The "owner" of the lock may not be empty' if owner.empty? elapsed(@loog, level: Logger::INFO) do post( home.append('unlock').append(pname), { 'owner' => owner } ) throw :"Job name #{pname.inspect} unlocked at #{@host}" end end |
#verified(id) ⇒ String
Read and return the verification verdict of the job.
212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/baza-rb.rb', line 212 def verified(id) raise 'The ID of the job is nil' if id.nil? raise 'The ID of the job must be a positive integer' unless id.positive? verdict = '' elapsed(@loog, level: Logger::INFO) do ret = get(home.append('jobs').append(id).append('verified.txt')) verdict = ret.body throw :"The verdict of the job ##{id} is #{verdict.inspect}" end verdict end |
#whoami ⇒ String
Get GitHub login name of the logged in user.
85 86 87 88 89 90 91 92 93 |
# File 'lib/baza-rb.rb', line 85 def whoami nick = nil elapsed(@loog, level: Logger::INFO) do ret = get(home.append('whoami')) nick = ret.body throw :"I know that I am @#{nick}, at #{@host}" end nick end |