diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-24 15:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-24 15:09:00 +0300 |
commit | ae78b85a25cb0c19c3d6a2e4e6c7ca91ed50787d (patch) | |
tree | c53ad0fcdab26725814f1dc5267f6a04ebe4cf73 /lib/gitlab/reference_counter.rb | |
parent | 38149afcf95e7669a7a99828c579d185b70c04dc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/reference_counter.rb')
-rw-r--r-- | lib/gitlab/reference_counter.rb | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/lib/gitlab/reference_counter.rb b/lib/gitlab/reference_counter.rb index 1c43de35816..5fdfa5e75ed 100644 --- a/lib/gitlab/reference_counter.rb +++ b/lib/gitlab/reference_counter.rb @@ -1,20 +1,42 @@ # frozen_string_literal: true module Gitlab + # Reference Counter + # + # A reference counter is used as a mechanism to identify when + # a repository is being accessed by a writable operation. + # + # Maintenance operations would use this as a clue to when it should + # execute significant changes in order to avoid disrupting running traffic class ReferenceCounter REFERENCE_EXPIRE_TIME = 600 attr_reader :gl_repository, :key + # Reference Counter instance + # + # @example + # Gitlab::ReferenceCounter.new('project-1') + # + # @see Gitlab::GlRepository::RepoType.identifier_for_repositorable + # @param [String] gl_repository repository identifier def initialize(gl_repository) @gl_repository = gl_repository @key = "git-receive-pack-reference-counter:#{gl_repository}" end + # Return the actual counter value + # + # @return [Integer] value def value - Gitlab::Redis::SharedState.with { |redis| (redis.get(key) || 0).to_i } + Gitlab::Redis::SharedState.with do |redis| + (redis.get(key) || 0).to_i + end end + # Increase the counter + # + # @return [Boolean] whether operation was a success def increase redis_cmd do |redis| redis.incr(key) @@ -22,26 +44,51 @@ module Gitlab end end - # rubocop:disable Gitlab/RailsLogger + # Decrease the counter + # + # @return [Boolean] whether operation was a success def decrease redis_cmd do |redis| current_value = redis.decr(key) if current_value < 0 + # rubocop:disable Gitlab/RailsLogger Rails.logger.warn("Reference counter for #{gl_repository} decreased" \ - " when its value was less than 1. Reseting the counter.") + " when its value was less than 1. Resetting the counter.") + # rubocop:enable Gitlab/RailsLogger redis.del(key) end end end - # rubocop:enable Gitlab/RailsLogger + + # Reset the reference counter + # + # @private Used internally by SRE and debugging purpose + # @return [Boolean] whether reset was a success + def reset! + redis_cmd do |redis| + redis.del(key) + end + end + + # When the reference counter would expire + # + # @api private Used internally by SRE and debugging purpose + # @return [Integer] Number in seconds until expiration or false if never + def expires_in + Gitlab::Redis::SharedState.with do |redis| + redis.ttl(key) + end + end private def redis_cmd Gitlab::Redis::SharedState.with { |redis| yield(redis) } + true rescue => e Rails.logger.warn("GitLab: An unexpected error occurred in writing to Redis: #{e}") # rubocop:disable Gitlab/RailsLogger + false end end |