2013-08-13 11:46:15 +01:00
|
|
|
module Sidetiq
|
|
|
|
class Lock # :nodoc: all
|
2013-09-16 12:01:37 +01:00
|
|
|
include Logging
|
|
|
|
|
2013-08-13 11:46:15 +01:00
|
|
|
attr_reader :key, :timeout
|
|
|
|
|
|
|
|
OWNER = "#{Socket.gethostname}:#{Process.pid}"
|
|
|
|
|
|
|
|
def initialize(key, timeout = Sidetiq.config.lock_expire)
|
|
|
|
@key = key.kind_of?(Class) ? "sidetiq:#{key.name}:lock" : "sidetiq:#{key}:lock"
|
|
|
|
@timeout = timeout
|
|
|
|
end
|
|
|
|
|
|
|
|
def synchronize
|
|
|
|
Sidekiq.redis do |redis|
|
|
|
|
if lock(redis)
|
2013-09-16 12:01:37 +01:00
|
|
|
debug "Sidetiq::Clock lock #{key}"
|
2013-08-13 11:46:15 +01:00
|
|
|
|
|
|
|
begin
|
|
|
|
yield redis
|
|
|
|
ensure
|
|
|
|
unlock(redis)
|
2013-09-16 12:01:37 +01:00
|
|
|
debug "Sidetiq::Clock unlock #{key}"
|
2013-08-13 11:46:15 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def lock(redis)
|
|
|
|
acquired = false
|
|
|
|
|
|
|
|
watch(redis, key) do
|
|
|
|
if !redis.exists(key)
|
|
|
|
acquired = !!redis.multi do |multi|
|
|
|
|
multi.psetex(key, timeout, OWNER)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
acquired
|
|
|
|
end
|
|
|
|
|
|
|
|
def unlock(redis)
|
|
|
|
watch(redis, key) do
|
|
|
|
if redis.get(key) == OWNER
|
|
|
|
redis.multi do |multi|
|
|
|
|
multi.del(key)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def watch(redis, *args)
|
|
|
|
redis.watch(*args)
|
|
|
|
|
|
|
|
begin
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
redis.unwatch
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|