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>2021-09-01 18:10:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-01 18:10:20 +0300
commit9c191c0b942eb08360f4d64c038c435b1156e15f (patch)
tree18ac3c7c2d816ffa4898202102cb889c2c6ca5a7 /lib/gitlab/issuables_count_for_state.rb
parent219501933150525be819f047d3196969ee914c47 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/issuables_count_for_state.rb')
-rw-r--r--lib/gitlab/issuables_count_for_state.rb47
1 files changed, 44 insertions, 3 deletions
diff --git a/lib/gitlab/issuables_count_for_state.rb b/lib/gitlab/issuables_count_for_state.rb
index 6b33b60e850..660877b964a 100644
--- a/lib/gitlab/issuables_count_for_state.rb
+++ b/lib/gitlab/issuables_count_for_state.rb
@@ -5,11 +5,14 @@ module Gitlab
class IssuablesCountForState
# The name of the Gitlab::SafeRequestStore cache key.
CACHE_KEY = :issuables_count_for_state
+ # The expiration time for the Rails cache.
+ CACHE_EXPIRES_IN = 10.minutes
+ THRESHOLD = 1000
# The state values that can be safely casted to a Symbol.
STATES = %w[opened closed merged all].freeze
- attr_reader :project
+ attr_reader :project, :finder
def self.declarative_policy_class
'IssuablePolicy'
@@ -18,11 +21,12 @@ module Gitlab
# finder - The finder class to use for retrieving the issuables.
# fast_fail - restrict counting to a shorter period, degrading gracefully on
# failure
- def initialize(finder, project = nil, fast_fail: false)
+ def initialize(finder, project = nil, fast_fail: false, store_in_redis_cache: false)
@finder = finder
@project = project
@fast_fail = fast_fail
@cache = Gitlab::SafeRequestStore[CACHE_KEY] ||= initialize_cache
+ @store_in_redis_cache = store_in_redis_cache
end
def for_state_or_opened(state = nil)
@@ -52,7 +56,16 @@ module Gitlab
private
def cache_for_finder
- @cache[@finder]
+ cached_counts = Rails.cache.read(redis_cache_key, cache_options) if cache_issues_count?
+
+ cached_counts ||= @cache[finder]
+ return cached_counts if cached_counts.empty?
+
+ if cache_issues_count? && cached_counts.values.all? { |count| count >= THRESHOLD }
+ Rails.cache.write(redis_cache_key, cached_counts, cache_options)
+ end
+
+ cached_counts
end
def cast_state_to_symbol?(state)
@@ -108,5 +121,33 @@ module Gitlab
"Count of failed calls to IssuableFinder#count_by_state with fast failure"
).increment
end
+
+ def cache_issues_count?
+ @store_in_redis_cache &&
+ finder.instance_of?(IssuesFinder) &&
+ parent_group.present? &&
+ !params_include_filters?
+ end
+
+ def parent_group
+ finder.params.group
+ end
+
+ def redis_cache_key
+ ['group', parent_group&.id, 'issues']
+ end
+
+ def cache_options
+ { expires_in: CACHE_EXPIRES_IN }
+ end
+
+ def params_include_filters?
+ non_filtering_params = %i[
+ scope state sort group_id include_subgroups
+ attempt_group_search_optimizations non_archived issue_types
+ ]
+
+ finder.params.except(*non_filtering_params).values.any?
+ end
end
end