Class: Cosmo::Job::Limit
- Inherits:
-
Object
- Object
- Cosmo::Job::Limit
- Defined in:
- lib/cosmo/job/limit.rb,
sig/cosmo/job/limit.rbs
Overview
Distributed concurrency limiter backed by NATS Key-Value with per-message TTL.
Each unit of concurrency is a numbered KV slot:
"{concurrency_key}/0", "{concurrency_key}/1", ..., "{concurrency_key}/{limit-1}"
Acquiring a slot is a single atomic set (CAS with last-revision=0).
Only one worker can win a given slot; losers try the next number.
When a job finishes, the slot is erased; if the worker crashes, NATS
expires it automatically via the per-message Nats-TTL header. Both
paths leave the slot equally empty -- no tombstone, no delete marker.
Constant Summary collapse
- BUCKET =
"cosmo_jobs_limits"
Class Method Summary collapse
Instance Method Summary collapse
-
#acquire(key, jid:, limit:, duration:) ⇒ String?
Try to acquire one of the numbered slots for
key. -
#initialize ⇒ Limit
constructor
A new instance of Limit.
-
#release(slot) ⇒ void
Release a previously acquired slot.
Constructor Details
Class Method Details
.instance ⇒ Limit
18 19 20 |
# File 'lib/cosmo/job/limit.rb', line 18 def self.instance @instance ||= new end |
Instance Method Details
#acquire(key, jid:, limit:, duration:) ⇒ String?
Try to acquire one of the numbered slots for key.
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/cosmo/job/limit.rb', line 33 def acquire(key, jid:, limit:, duration:) 0.upto(limit - 1) do |i| slot = "#{key}/#{i}" @kv.set(slot, jid, ttl: duration) return slot rescue NATS::KeyValue::KeyWrongLastSequenceError next # slot is live, try the next one end nil # all slots occupied end |
#release(slot) ⇒ void
This method returns an undefined value.
Release a previously acquired slot. Erases the slot entirely (no tombstone left behind) so a released slot looks identical to one reclaimed by Nats-TTL expiry -- callers never have to special-case a delete marker.
48 49 50 51 52 |
# File 'lib/cosmo/job/limit.rb', line 48 def release(slot) @kv.erase(slot) rescue NATS::Error # best effort — slot TTL will reclaim it if erase fails end |