Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-06 09:09:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-06 09:09:36 +0300
commit0c4b9cacd575b3e71e41a13f042062b3adcb4caf (patch)
treefd06e55f276c1fa42327a41860e328b46a8cb8ee /lib/gitlab/exclusive_lease_helpers.rb
parent6c005ae9783ad6752e3082d05e1053d20d8da92a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/exclusive_lease_helpers.rb')
-rw-r--r--lib/gitlab/exclusive_lease_helpers.rb43
1 files changed, 24 insertions, 19 deletions
diff --git a/lib/gitlab/exclusive_lease_helpers.rb b/lib/gitlab/exclusive_lease_helpers.rb
index a1504833039..10762d83588 100644
--- a/lib/gitlab/exclusive_lease_helpers.rb
+++ b/lib/gitlab/exclusive_lease_helpers.rb
@@ -6,33 +6,38 @@ module Gitlab
FailedToObtainLockError = Class.new(StandardError)
##
- # This helper method blocks a process/thread until the other process cancel the obrainted lease key.
+ # 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.
#
- # Note: It's basically discouraged to use this method in the unicorn's thread,
- # because it holds the connection until all `retries` is consumed.
+ # 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)
+ #
+ # Note: It's basically discouraged to use this method in a unicorn thread,
+ # because this ties up all thread related resources until all `retries` are consumed.
# This could potentially eat up all connection pools.
def in_lock(key, ttl: 1.minute, retries: 10, sleep_sec: 0.01.seconds)
raise ArgumentError, 'Key needs to be specified' unless key
- lease = Gitlab::ExclusiveLease.new(key, timeout: ttl)
- retried = false
- max_attempts = 1 + retries
-
- until uuid = lease.try_obtain
- # Keep trying until we obtain the lease. To prevent hammering Redis too
- # much we'll wait for a bit.
- attempt_number = max_attempts - retries
- delay = sleep_sec.respond_to?(:call) ? sleep_sec.call(attempt_number) : sleep_sec
-
- sleep(delay)
- (retries -= 1) < 0 ? break : retried ||= true
- end
+ lease = SleepingLock.new(key, timeout: ttl, delay: sleep_sec)
- raise FailedToObtainLockError, 'Failed to obtain a lock' unless uuid
+ lease.obtain(1 + retries)
- yield(retried)
+ yield(lease.retried?)
ensure
- Gitlab::ExclusiveLease.cancel(key, uuid)
+ lease&.cancel
end
end
end