debian-mirror-gitlab/lib/gitlab/exclusive_lease_helpers.rb

44 lines
2 KiB
Ruby
Raw Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
2018-11-08 19:23:39 +05:30
module Gitlab
# This module provides helper methods which are intregrated with GitLab::ExclusiveLease
module ExclusiveLeaseHelpers
FailedToObtainLockError = Class.new(StandardError)
##
2020-05-24 23:13:21 +05:30
# This helper method blocks a process/thread until the lease can be acquired, either due to
# the lease TTL expiring, or due to the current holder explicitly releasing
# their hold.
2018-11-08 19:23:39 +05:30
#
2020-05-24 23:13:21 +05:30
# If the lease cannot be obtained, raises `FailedToObtainLockError`.
#
# @param [String] key The lock the thread will try to acquire. Only one thread
# in one process across all Rails instances can hold this named lock at any
# one time.
# @param [Float] ttl: The length of time the lock will be valid for. The lock
# will be automatically be released after this time, so any work should be
# completed within this time.
# @param [Integer] retries: The maximum number of times we will re-attempt
# to acquire the lock. The maximum number of attempts will be `retries + 1`:
# one for the initial attempt, and then one for every re-try.
# @param [Float|Proc] sleep_sec: Either a number of seconds to sleep, or
# a proc that computes the sleep time given the number of preceding attempts
# (from 1 to retries - 1)
#
2021-09-04 01:27:46 +05:30
# Note: It's basically discouraged to use this method in a webserver thread,
2020-05-24 23:13:21 +05:30
# because this ties up all thread related resources until all `retries` are consumed.
2018-11-08 19:23:39 +05:30
# This could potentially eat up all connection pools.
def in_lock(key, ttl: 1.minute, retries: 10, sleep_sec: 0.01.seconds)
2019-02-15 15:39:39 +05:30
raise ArgumentError, 'Key needs to be specified' unless key
2020-05-24 23:13:21 +05:30
lease = SleepingLock.new(key, timeout: ttl, delay: sleep_sec)
2018-11-08 19:23:39 +05:30
2020-05-24 23:13:21 +05:30
lease.obtain(1 + retries)
2018-11-08 19:23:39 +05:30
2021-01-03 14:25:43 +05:30
yield(lease.retried?, lease)
2018-11-08 19:23:39 +05:30
ensure
2020-05-24 23:13:21 +05:30
lease&.cancel
2018-11-08 19:23:39 +05:30
end
end
end