Class: Honker::Queue

Inherits:
Object
  • Object
show all
Defined in:
lib/honker.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db, name, visibility_timeout_s:, max_attempts:) ⇒ Queue

Returns a new instance of Queue.



360
361
362
363
364
365
# File 'lib/honker.rb', line 360

def initialize(db, name, visibility_timeout_s:, max_attempts:)
  @db = db
  @name = name
  @visibility_timeout_s = visibility_timeout_s
  @max_attempts = max_attempts
end

Instance Attribute Details

#max_attemptsObject (readonly)

Returns the value of attribute max_attempts.



358
359
360
# File 'lib/honker.rb', line 358

def max_attempts
  @max_attempts
end

#nameObject (readonly)

Returns the value of attribute name.



358
359
360
# File 'lib/honker.rb', line 358

def name
  @name
end

Instance Method Details

#_ack(job_id, worker_id) ⇒ Object

Internal: invoked by Job#ack.



420
421
422
# File 'lib/honker.rb', line 420

def _ack(job_id, worker_id)
  @db.db.get_first_row("SELECT honker_ack(?, ?)", [job_id, worker_id])[0] == 1
end

#_fail(job_id, worker_id, err_msg) ⇒ Object

Internal: invoked by Job#fail.



433
434
435
436
437
438
# File 'lib/honker.rb', line 433

def _fail(job_id, worker_id, err_msg)
  @db.db.get_first_row(
    "SELECT honker_fail(?, ?, ?)",
    [job_id, worker_id, err_msg],
  )[0] == 1
end

#_heartbeat(job_id, worker_id, extend_s) ⇒ Object

Internal: invoked by Job#heartbeat.



441
442
443
444
445
446
# File 'lib/honker.rb', line 441

def _heartbeat(job_id, worker_id, extend_s)
  @db.db.get_first_row(
    "SELECT honker_heartbeat(?, ?, ?)",
    [job_id, worker_id, extend_s],
  )[0] == 1
end

#_retry(job_id, worker_id, delay_s, err_msg) ⇒ Object

Internal: invoked by Job#retry.



425
426
427
428
429
430
# File 'lib/honker.rb', line 425

def _retry(job_id, worker_id, delay_s, err_msg)
  @db.db.get_first_row(
    "SELECT honker_retry(?, ?, ?, ?)",
    [job_id, worker_id, delay_s, err_msg],
  )[0] == 1
end

#ack_batch(ids, worker_id) ⇒ Object

Ack multiple jobs in one transaction. Returns the number acked.



403
404
405
406
407
408
# File 'lib/honker.rb', line 403

def ack_batch(ids, worker_id)
  @db.db.get_first_row(
    "SELECT honker_ack_batch(?, ?)",
    [JSON.dump(ids), worker_id],
  )[0]
end

#cancel(job_id) ⇒ Object

Delete a pending or processing job by id. Returns true iff a row was removed. Idempotent on missing.

IMPORTANT: cancel does NOT interrupt a worker currently running the handler. It invalidates the worker's claim — its next ack/heartbeat returns false. If you need the handler to actually halt, build that signal in your app.



455
456
457
458
459
# File 'lib/honker.rb', line 455

def cancel(job_id)
  n = @db.db.get_first_row("SELECT honker_cancel(?)", [job_id])[0]
  @db.mark_updated if n.positive?
  n.positive?
end

#claim_batch(worker_id, n) ⇒ Object

Claim up to n jobs atomically. Returns an array of Job.



389
390
391
392
393
394
395
# File 'lib/honker.rb', line 389

def claim_batch(worker_id, n)
  rows_json = @db.db.get_first_row(
    "SELECT honker_claim_batch(?, ?, ?, ?)",
    [@name, worker_id, n, @visibility_timeout_s],
  )[0]
  JSON.parse(rows_json).map { |r| Job.new(self, r) }
end

#claim_one(worker_id) ⇒ Object

Claim a single job or nil if the queue is empty.



398
399
400
# File 'lib/honker.rb', line 398

def claim_one(worker_id)
  claim_batch(worker_id, 1).first
end

#enqueue(payload, delay: nil, run_at: nil, priority: 0, expires: nil) ⇒ Object

Enqueue a job. Returns the inserted row id.

q.enqueue({to: "alice"}, delay: 60, priority: 10, expires: 3600)


370
371
372
373
374
375
376
# File 'lib/honker.rb', line 370

def enqueue(payload, delay: nil, run_at: nil, priority: 0, expires: nil)
  row = @db.db.get_first_row(
    "SELECT honker_enqueue(?, ?, ?, ?, ?, ?, ?)",
    [@name, JSON.dump(payload), run_at, delay, priority, @max_attempts, expires],
  )
  row[0]
end

#enqueue_tx(tx, payload, delay: nil, run_at: nil, priority: 0, expires: nil) ⇒ Object

Enqueue inside an open transaction. Atomic with whatever else ran on the same tx.



380
381
382
383
384
385
386
# File 'lib/honker.rb', line 380

def enqueue_tx(tx, payload, delay: nil, run_at: nil, priority: 0, expires: nil)
  row = tx.query_row(
    "SELECT honker_enqueue(?, ?, ?, ?, ?, ?, ?)",
    [@name, JSON.dump(payload), run_at, delay, priority, @max_attempts, expires],
  )
  row[0]
end

#get_job(job_id) ⇒ Object

Read a single job row by id. Returns a Hash with the row fields, or nil if the job has been ack'd, dead'd, or never existed.



463
464
465
466
467
468
# File 'lib/honker.rb', line 463

def get_job(job_id)
  raw = @db.db.get_first_row("SELECT honker_get_job(?)", [job_id])[0]
  return nil if raw.nil? || raw.empty?

  JSON.parse(raw)
end

#sweep_expiredObject

Sweep this queue's expired claims back to pending. Returns the number of rows reclaimed.



412
413
414
415
416
417
# File 'lib/honker.rb', line 412

def sweep_expired
  @db.db.get_first_row(
    "SELECT honker_sweep_expired(?)",
    [@name],
  )[0]
end