Class: ArResqueCounterCache::IncrementCountersWorker
- Inherits:
-
Object
- Object
- ArResqueCounterCache::IncrementCountersWorker
- Includes:
- Resque::Plugins::UniqueJob
- Defined in:
- lib/ar-resque-counter-cache/increment_counters_worker.rb
Overview
ArResqueCounterCache will very quickly increment a counter cache in Redis, which will then later be updated by a Resque job. Using require-loner, we can ensure that only one job per payload is enqueued at a time.
Class Method Summary collapse
- .cache_and_enqueue(parent_class, id, column, direction) ⇒ Object
-
.cache_key(*args) ⇒ Object
args: (parent_class, id, column).
-
.identifier(*args) ⇒ Object
args: (parent_class, id, column).
- .perform(parent_class, id, column) ⇒ Object
- .redis ⇒ Object
Class Method Details
.cache_and_enqueue(parent_class, id, column, direction) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 30 def self.cache_and_enqueue(parent_class, id, column, direction) parent_class = parent_class.to_s key = cache_key(parent_class, id, column) if direction == :increment redis.incr(key) elsif direction == :decrement redis.decr(key) else raise ArgumentError, "Must call ArResqueCounterCache::IncrementCountersWorker with :increment or :decrement" end ::Resque.enqueue(self, parent_class, id, column) end |
.cache_key(*args) ⇒ Object
args: (parent_class, id, column)
53 54 55 |
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 53 def self.cache_key(*args) "ar-resque-counter-cache:#{identifier(*args)}" end |
.identifier(*args) ⇒ Object
args: (parent_class, id, column)
48 49 50 |
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 48 def self.identifier(*args) args.join('-') end |
.perform(parent_class, id, column) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 57 def self.perform(parent_class, id, column) key = cache_key(parent_class, id, column) if (delta = redis.getset(key, 0).to_i) != 0 begin parent_class = ::Resque.constantize(parent_class) parent_class.find(id) parent_class.update_counters(id, column => delta) rescue Exception => e # If anything happens, set back the counter cache. if delta > 0 redis.incrby(key, delta) elsif delta < 0 redis.decrby(key, -delta) end raise e end end end |
.redis ⇒ Object
43 44 45 |
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 43 def self.redis @redis || ::Resque.redis end |