diff options
Diffstat (limited to 'app/services/concerns/exclusive_lease_lock.rb')
-rw-r--r-- | app/services/concerns/exclusive_lease_lock.rb | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/app/services/concerns/exclusive_lease_lock.rb b/app/services/concerns/exclusive_lease_lock.rb new file mode 100644 index 00000000000..6c8bc25ea16 --- /dev/null +++ b/app/services/concerns/exclusive_lease_lock.rb @@ -0,0 +1,21 @@ +module ExclusiveLeaseLock + extend ActiveSupport::Concern + + def in_lock(key, ttl: 1.minute, retry_max: 10, sleep_sec: 0.01.seconds) + lease = Gitlab::ExclusiveLease.new(key, timeout: ttl) + retry_count = 0 + + 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 retry_max < (retry_count += 1) + end + + raise WriteError, 'Failed to obtain write lock' unless uuid + + return yield + ensure + Gitlab::ExclusiveLease.cancel(key, uuid) + end +end |