Class: ActiveJob::Plugins::Resque::Solo::Lock

Inherits:
Object
  • Object
show all
Defined in:
lib/active_job/plugins/resque/solo/lock.rb

Constant Summary collapse

ACQUIRE_TTL =

TTLs in seconds

1.0
EXECUTE_TTL =
5.0

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Lock

Returns a new instance of Lock.



10
11
12
13
14
15
# File 'lib/active_job/plugins/resque/solo/lock.rb', line 10

def initialize(key)
  @redis = ::Resque.redis
  @uuid = ::SecureRandom.uuid
  @acquired = nil
  @key = key
end

Class Method Details

.try_acquire_release(key) { ... } ⇒ Boolean

Attempts to acquire a lock named by the key in Redis. If the lock is acquired, the block is executed. If the lock is not acquired, the block is not executed.

Parameters:

  • key (String)

    the key used to articulate the lock

Yields:

  • the block to execute if the lock can be acquired

Returns:

  • (Boolean)

    x if the block was executed, false if the block was not executed



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/active_job/plugins/resque/solo/lock.rb', line 24

def self.try_acquire_release(key)
  lock = Lock.new(key)

  extend_at = lock.try_acquire
  return false if extend_at.nil?

  begin
    yield(lock, extend_at)
  ensure
    lock.release
  end

  true
end

Instance Method Details

#extendObject



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/active_job/plugins/resque/solo/lock.rb', line 50

def extend
  extend_at = 1.year.from_now

  @redis.watch(@key) do
    if @redis.get(@key) == @uuid
      if @redis.multi{ |multi| multi.expire(@key, EXECUTE_TTL.to_i) }.present?
        extend_at = Time.now.utc + (EXECUTE_TTL.to_f / 2)
      end
    end
  end

  extend_at
end

#releaseObject



64
65
66
67
68
69
70
71
72
# File 'lib/active_job/plugins/resque/solo/lock.rb', line 64

def release
  @redis.watch(@key) do
    if @redis.get(@key) == @uuid
      @redis.multi do |multi|
        multi.del(@key)
      end
    end
  end
end

#try_acquireObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/active_job/plugins/resque/solo/lock.rb', line 39

def try_acquire
  extend_at = Time.now.utc + (ACQUIRE_TTL.to_f / 2)
  px = (ACQUIRE_TTL.to_f * 1000).to_i

  if @redis.set(@key, @uuid, px: px, nx: true)
    @acquired = @uuid
  end

  @acquired == @uuid ? extend_at : nil
end