Consider caching FindCommit call for the root ref
The FindCommit
RPC is one of the most popular ones: https://log.gprd.gitlab.net/goto/2690d5a0-5f4d-11ed-b0ec-930003e0679c.
Let's investigate whether is possible to cache it for the root ref. If we decide that it's reasonable to introduce this optimization, it makes sense to do it behind a feature flag. The changes may look something like:
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 3413b3e34249..8b3644385425 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -52,7 +52,7 @@ class Repository
gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? root_ref merged_branch_names
has_visible_content? issue_template_names_hash merge_request_template_names_hash
- user_defined_metrics_dashboard_paths xcode_project? has_ambiguous_refs?).freeze
+ user_defined_metrics_dashboard_paths xcode_project? has_ambiguous_refs? root_ref_commit).freeze
# Certain method caches should be refreshed when certain types of files are
# changed. This Hash maps file types (as returned by Gitlab::FileDetector) to
@@ -361,6 +361,10 @@ def expire_statistics_caches
expire_method_caches(%i(size commit_count))
end
+ def expire_root_ref_commit_cache
+ expire_method_caches(%i(root_ref_commit))
+ end
+
def expire_all_method_caches
expire_method_caches(CACHED_METHODS)
end
@@ -407,7 +411,7 @@ def expire_branch_cache(branch_name = nil)
end
def expire_root_ref_cache
- expire_method_caches(%i(root_ref))
+ expire_method_caches(%i(root_ref root_ref_commit))
end
# Expires the cache(s) used to determine if a repository is empty or not.
@@ -430,6 +434,7 @@ def expire_content_cache
expire_emptiness_caches
expire_exists_cache
expire_statistics_caches
+ expire_root_ref_commit_cache
end
def expire_status_cache
@@ -498,6 +503,7 @@ def after_change_head
# Runs code after a new commit has been pushed.
def after_push_commit(branch_name)
+ expire_root_ref_commit_cache
expire_statistics_caches
expire_branch_cache(branch_name)
@@ -1203,6 +1209,8 @@ def remove_prohibited_branches
# TODO Genericize finder, later split this on finders by Ref or Oid
# https://gitlab.com/gitlab-org/gitlab/issues/19877
def find_commit(oid_or_ref)
+ return ::Commit.from_hash(root_ref_commit, container) if oid_or_ref == root_ref
+
commit = if oid_or_ref.is_a?(Gitlab::Git::Commit)
oid_or_ref
else
@@ -1212,6 +1220,11 @@ def find_commit(oid_or_ref)
::Commit.new(commit, container) if commit
end
+ def root_ref_commit
+ Gitlab::Git::Commit.find(raw_repository, root_ref).to_hash
+ end
+ cache_method_asymmetrically :root_ref_commit
+
def redis_set_cache
@redis_set_cache ||= Gitlab::RepositorySetCache.new(self)
end