Class: ArResqueCounterCache::IncrementCountersWorker

Inherits:
Object
  • Object
show all
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

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

.redisObject



43
44
45
# File 'lib/ar-resque-counter-cache/increment_counters_worker.rb', line 43

def self.redis
  @redis || ::Resque.redis
end