1
0
Fork 0
mirror of https://github.com/endofunky/sidetiq.git synced 2022-11-09 13:53:30 -05:00
endofunky--sidetiq/lib/sidetiq/lock.rb
Tobias Svensson e0ebcaacd9 Move to actor-based concurrency.
Using plain threads in Sidekiq's Celluloid-based actor
model is a little bit like riding a motorcycle without
a helmet, so let's try to fit in a bit better.
2013-09-16 12:01:37 +01:00

65 lines
1.2 KiB
Ruby

module Sidetiq
class Lock # :nodoc: all
include Logging
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)
debug "Sidetiq::Clock lock #{key}"
begin
yield redis
ensure
unlock(redis)
debug "Sidetiq::Clock unlock #{key}"
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