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:
Diffstat (limited to 'lib/gitlab/optimistic_locking.rb')
-rw-r--r--lib/gitlab/optimistic_locking.rb61
1 files changed, 50 insertions, 11 deletions
diff --git a/lib/gitlab/optimistic_locking.rb b/lib/gitlab/optimistic_locking.rb
index d51d718c826..b29240985f1 100644
--- a/lib/gitlab/optimistic_locking.rb
+++ b/lib/gitlab/optimistic_locking.rb
@@ -2,22 +2,61 @@
module Gitlab
module OptimisticLocking
+ MAX_RETRIES = 100
+
module_function
- def retry_lock(subject, retries = nil, &block)
- retries ||= 100
- # TODO(Observability): We should be recording details of the number of retries and the duration of the total execution here
- ActiveRecord::Base.transaction do
- yield(subject)
- end
- rescue ActiveRecord::StaleObjectError
- retries -= 1
- raise unless retries >= 0
+ def retry_lock(subject, max_retries = MAX_RETRIES, name:, &block)
+ start_time = Gitlab::Metrics::System.monotonic_time
+ retry_attempts = 0
+
+ begin
+ ActiveRecord::Base.transaction do
+ yield(subject)
+ end
+ rescue ActiveRecord::StaleObjectError
+ raise unless retry_attempts < max_retries
+
+ subject.reset
- subject.reset
- retry
+ retry_attempts += 1
+ retry
+ ensure
+ retry_lock_histogram.observe({}, retry_attempts)
+
+ log_optimistic_lock_retries(
+ name: name,
+ retry_attempts: retry_attempts,
+ start_time: start_time)
+ end
end
alias_method :retry_optimistic_lock, :retry_lock
+
+ def log_optimistic_lock_retries(name:, retry_attempts:, start_time:)
+ return unless retry_attempts > 0
+
+ elapsed_time = Gitlab::Metrics::System.monotonic_time - start_time
+
+ retry_lock_logger.info(
+ message: "Optimistic Lock released with retries",
+ name: name,
+ retries: retry_attempts,
+ time_s: elapsed_time)
+ end
+
+ def retry_lock_logger
+ @retry_lock_logger ||= Gitlab::Services::Logger.build
+ end
+
+ def retry_lock_histogram
+ @retry_lock_histogram ||=
+ Gitlab::Metrics.histogram(
+ :gitlab_optimistic_locking_retries,
+ 'Number of retry attempts to execute optimistic retry lock',
+ {},
+ [0, 1, 2, 3, 5, 10, 50]
+ )
+ end
end
end