summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKerri Miller <kerrizor@kerrizor.com>2019-08-07 15:13:13 +0000
committerDouwe Maan <douwe@gitlab.com>2019-08-07 15:13:13 +0000
commit336d3ccc65d522633162b1f6b5fc54591c588221 (patch)
tree7dfea148c6e69f40e8f2a20b6dda683be4c617cc
parent35e49d3be0ffe58fef80c30f6b432312541b8a73 (diff)
downloadgitlab-ce-336d3ccc65d522633162b1f6b5fc54591c588221.tar.gz
Initial commit of WIP code for consideration
Squash this commit and reword before merging..
-rw-r--r--changelogs/unreleased/60449-reduce-gitaly-calls-when-rendering-commits-in-md.yml5
-rw-r--r--lib/banzai/filter/abstract_reference_filter.rb18
-rw-r--r--lib/banzai/filter/commit_reference_filter.rb17
-rw-r--r--lib/banzai/filter/issuable_reference_filter.rb18
-rw-r--r--spec/lib/banzai/filter/commit_reference_filter_spec.rb11
5 files changed, 48 insertions, 21 deletions
diff --git a/changelogs/unreleased/60449-reduce-gitaly-calls-when-rendering-commits-in-md.yml b/changelogs/unreleased/60449-reduce-gitaly-calls-when-rendering-commits-in-md.yml
new file mode 100644
index 00000000000..ef11e8743f6
--- /dev/null
+++ b/changelogs/unreleased/60449-reduce-gitaly-calls-when-rendering-commits-in-md.yml
@@ -0,0 +1,5 @@
+---
+title: Batch processing of commit refs in markdown processing
+merge_request: 31037
+author:
+type: performance
diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb
index 0224dd8fcd1..52af28ce8ec 100644
--- a/lib/banzai/filter/abstract_reference_filter.rb
+++ b/lib/banzai/filter/abstract_reference_filter.rb
@@ -337,6 +337,24 @@ module Banzai
@current_project_namespace_path ||= project&.namespace&.full_path
end
+ def records_per_parent
+ @_records_per_project ||= {}
+
+ @_records_per_project[object_class.to_s.underscore] ||= begin
+ hash = Hash.new { |h, k| h[k] = {} }
+
+ parent_per_reference.each do |path, parent|
+ record_ids = references_per_parent[path]
+
+ parent_records(parent, record_ids).each do |record|
+ hash[parent][record_identifier(record)] = record
+ end
+ end
+
+ hash
+ end
+ end
+
private
def full_project_path(namespace, project_ref)
diff --git a/lib/banzai/filter/commit_reference_filter.rb b/lib/banzai/filter/commit_reference_filter.rb
index c3e5ac41cb8..e1d7b36b9a2 100644
--- a/lib/banzai/filter/commit_reference_filter.rb
+++ b/lib/banzai/filter/commit_reference_filter.rb
@@ -19,12 +19,11 @@ module Banzai
end
def find_object(project, id)
- return unless project.is_a?(Project)
+ return unless project.is_a?(Project) && project.valid_repo?
- if project && project.valid_repo?
- # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/43894
- Gitlab::GitalyClient.allow_n_plus_1_calls { project.commit(id) }
- end
+ _, record = records_per_parent[project].detect { |k, _v| Gitlab::Git.shas_eql?(k, id) }
+
+ record
end
def referenced_merge_request_commit_shas
@@ -66,6 +65,14 @@ module Banzai
private
+ def record_identifier(record)
+ record.id
+ end
+
+ def parent_records(parent, ids)
+ parent.commits_by(oids: ids.to_a)
+ end
+
def noteable
context[:noteable]
end
diff --git a/lib/banzai/filter/issuable_reference_filter.rb b/lib/banzai/filter/issuable_reference_filter.rb
index 2963cba91e8..b91ba9f7256 100644
--- a/lib/banzai/filter/issuable_reference_filter.rb
+++ b/lib/banzai/filter/issuable_reference_filter.rb
@@ -3,22 +3,8 @@
module Banzai
module Filter
class IssuableReferenceFilter < AbstractReferenceFilter
- def records_per_parent
- @records_per_project ||= {}
-
- @records_per_project[object_class.to_s.underscore] ||= begin
- hash = Hash.new { |h, k| h[k] = {} }
-
- parent_per_reference.each do |path, parent|
- record_ids = references_per_parent[path]
-
- parent_records(parent, record_ids).each do |record|
- hash[parent][record.iid.to_i] = record
- end
- end
-
- hash
- end
+ def record_identifier(record)
+ record.iid.to_i
end
def find_object(parent, iid)
diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
index 1bc0335cfc0..326703eea05 100644
--- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
@@ -105,6 +105,17 @@ describe Banzai::Filter::CommitReferenceFilter do
expect(doc.css('a').first[:href]).to eq(url)
end
+
+ context "a doc with many (29) strings that could be SHAs" do
+ let!(:oids) { noteable.commits.collect(&:id) }
+
+ it 'makes only a single request to Gitaly' do
+ expect(Gitlab::GitalyClient).to receive(:allow_n_plus_1_calls).exactly(0).times
+ expect(Gitlab::Git::Commit).to receive(:batch_by_oid).once.and_call_original
+
+ reference_filter("A big list of SHAs #{oids.join(", ")}", noteable: noteable)
+ end
+ end
end
end