From 6653ccc011dec86e5140a5d09ea3b2357eab6714 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 12 Mar 2021 16:26:10 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-10-stable-ee --- lib/gitlab/optimistic_locking.rb | 61 ++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) (limited to 'lib/gitlab/optimistic_locking.rb') 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 -- cgit v1.2.3