summaryrefslogtreecommitdiff
path: root/app/services/concerns/exclusive_lease_lock.rb
blob: 8da54b0d15d9e540b3762f2c5057df728864882f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module ExclusiveLeaseLock
  extend ActiveSupport::Concern

  FailedToObtainLockError = Class.new(StandardError)

  def in_lock(key, ttl: 1.minute, retries: 10, sleep_sec: 0.01.seconds)
    lease = Gitlab::ExclusiveLease.new(key, timeout: ttl)

    until uuid = lease.try_obtain
      # Keep trying until we obtain the lease. To prevent hammering Redis too
      # much we'll wait for a bit.
      sleep(sleep_sec)
      break if (retries -= 1) < 0
    end

    raise FailedToObtainLockError, 'Failed to obtain a lock' unless uuid

    return yield
  ensure
    Gitlab::ExclusiveLease.cancel(key, uuid)
  end
end