summaryrefslogtreecommitdiff
path: root/app/models/issue.rb
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2017-08-17 17:21:25 +0200
committerYorick Peterse <yorickpeterse@gmail.com>2017-08-18 13:09:09 +0200
commit049578ff6f75a5ab4ceaabdefa988045f1895d89 (patch)
tree414a34a32bdccbd2405c56619c6f8e1005a48bb6 /app/models/issue.rb
parent133c72ae421b97f483417d5c427721336719b5da (diff)
downloadgitlab-ce-cache-issue-and-mr-counts.tar.gz
Cache the number of open issues and merge requestscache-issue-and-mr-counts
Every project page displays a navigation menu that in turn displays the number of open issues and merge requests. This means that for every project page we run two COUNT(*) queries, each taking up roughly 30 milliseconds on GitLab.com. By caching these numbers and refreshing them whenever necessary we can reduce loading times of all these pages by up to roughly 60 milliseconds. The number of open issues _includes_ confidential issues, even if you can not see these issues. This is a trade-off to keep the code simple and to ensure refreshing the data only needs 2 COUNT(*) queries instead of 3. Further, by including all issues we don't need any additional work to determine if the issue counter we display to a user should include confidential issues or not. This does mean that if a project has 10 issues of which 5 are confidential, everybody (that can see the project) will see the number 10. Because we now have 3 similar counting service classes the code previously used in Projects::ForksCountService has mostly been moved to Projects::CountService, which in turn is reused by the various service classes. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/36622
Diffstat (limited to 'app/models/issue.rb')
-rw-r--r--app/models/issue.rb5
1 files changed, 5 insertions, 0 deletions
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 1c948c8957e..9dbc018ed3e 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -54,6 +54,7 @@ class Issue < ActiveRecord::Base
scope :preload_associations, -> { preload(:labels, project: :namespace) }
after_save :expire_etag_cache
+ after_commit :update_project_counter_caches, on: :destroy
attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true
@@ -269,6 +270,10 @@ class Issue < ActiveRecord::Base
end
end
+ def update_project_counter_caches
+ Projects::OpenIssuesCountService.new(project).refresh_cache
+ end
+
private
# Returns `true` if the given User can read the current Issue.