class Continuity::RedisBackend
Constants
- LAST_SCHED_KEY
- LOCK_KEY
Public Class Methods
new(redis, frequency = 10, lock_timeout = 30)
click to toggle source
# File lib/continuity/redis_backend.rb, line 6 def initialize(redis, frequency = 10, lock_timeout = 30) @redis = redis @lock_timeout = lock_timeout @frequency = frequency end
Public Instance Methods
lock_for_scheduling(now) { |now| ... }
click to toggle source
# File lib/continuity/redis_backend.rb, line 12 def lock_for_scheduling(now) scheduled_up_to = @redis.get(LAST_SCHED_KEY).to_i # bootstrap if scheduled_up_to == 0 lock(now) do # double check that someone else has bootstrapped # since we fetched the key scheduled_up_to = @redis.get(LAST_SCHED_KEY).to_i if scheduled_up_to == 0 yield now - 1 @redis.set(LAST_SCHED_KEY, now) return now else return scheduled_up_to end end end # this is tricky, we only want to attempt a lock # if there is a possibility we can schedule things. # BUT, once we attain a lock we need to make sure # someone else hasn't already scheduled that period if (now - scheduled_up_to) >= @frequency lock(now) do scheduled_up_to = @redis.get(LAST_SCHED_KEY).to_i if (now - scheduled_up_to) >= @frequency # good we should still schedule yield scheduled_up_to @redis.set(LAST_SCHED_KEY, now) scheduled_up_to = now end end end scheduled_up_to end
Private Instance Methods
lock(now) { || ... }
click to toggle source
code.google.com/p/redis/wiki/SetnxCommand
# File lib/continuity/redis_backend.rb, line 55 def lock(now) lock_expiration = now + @lock_timeout + 1 res = @redis.setnx(LOCK_KEY, lock_expiration) acquired_lock = false if res acquired_lock = true yield else current_expiration = @redis.get(LOCK_KEY).to_i if current_expiration < now new_expiration = now + @lock_timeout + 1 if current_expiration == @redis.getset(LOCK_KEY, new_expiration).to_i acquired_lock = true yield end end end ensure if acquired_lock @redis.del(LOCK_KEY) end end