Commit f270ad47 authored by James Edwards-Jones's avatar James Edwards-Jones

Avoid slow File Lock checks when not used

Also avoid double commit lookup during file lock check by reusing
memoized commits.
parent 0a5e840b
...@@ -57,7 +57,7 @@ module EE ...@@ -57,7 +57,7 @@ module EE
commit_validation = push_rule.try(:commit_validation?) commit_validation = push_rule.try(:commit_validation?)
# if newrev is blank, the branch was deleted # if newrev is blank, the branch was deleted
return if deletion? || !(commit_validation || validate_path_locks?) return if deletion? || !commit_validation
commits.each do |commit| commits.each do |commit|
push_rule_commit_check(commit) push_rule_commit_check(commit)
...@@ -144,6 +144,19 @@ module EE ...@@ -144,6 +144,19 @@ module EE
end end
end end
override :should_run_commit_validations?
def should_run_commit_validations?
super || validate_path_locks? || push_rule_checks_commit?
end
def push_rule_checks_commit?
return false unless push_rule
push_rule.max_file_size > 0 ||
push_rule.file_name_regex.present? ||
push_rule.prevent_secrets
end
override :validations_for_commit override :validations_for_commit
def validations_for_commit(commit) def validations_for_commit(commit)
validations = super validations = super
......
...@@ -236,7 +236,7 @@ describe Gitlab::Checks::ChangeAccess do ...@@ -236,7 +236,7 @@ describe Gitlab::Checks::ChangeAccess do
old_rev = new_rev if new_rev old_rev = new_rev if new_rev
new_rev = project.repository.create_file(user, file_path, "commit #{file_path}", message: "commit #{file_path}", branch_name: "master") new_rev = project.repository.create_file(user, file_path, "commit #{file_path}", message: "commit #{file_path}", branch_name: "master")
allow(project.repository).to receive(:new_commits).and_return( allow(subject).to receive(:commits).and_return(
project.repository.commits_between(old_rev, new_rev) project.repository.commits_between(old_rev, new_rev)
) )
......
...@@ -122,6 +122,7 @@ module Gitlab ...@@ -122,6 +122,7 @@ module Gitlab
def commits_check def commits_check
return if deletion? || newrev.nil? return if deletion? || newrev.nil?
return unless should_run_commit_validations?
# n+1: https://gitlab.com/gitlab-org/gitlab-ee/issues/3593 # n+1: https://gitlab.com/gitlab-org/gitlab-ee/issues/3593
::Gitlab::GitalyClient.allow_n_plus_1_calls do ::Gitlab::GitalyClient.allow_n_plus_1_calls do
...@@ -140,6 +141,10 @@ module Gitlab ...@@ -140,6 +141,10 @@ module Gitlab
private private
def should_run_commit_validations?
commit_check.validate_lfs_file_locks?
end
def updated_from_web? def updated_from_web?
protocol == 'web' protocol == 'web'
end end
...@@ -177,7 +182,7 @@ module Gitlab ...@@ -177,7 +182,7 @@ module Gitlab
end end
def commits def commits
project.repository.new_commits(newrev) @commits ||= project.repository.new_commits(newrev)
end end
end end
end end
......
...@@ -35,14 +35,14 @@ module Gitlab ...@@ -35,14 +35,14 @@ module Gitlab
end end
end end
private
def validate_lfs_file_locks? def validate_lfs_file_locks?
strong_memoize(:validate_lfs_file_locks) do strong_memoize(:validate_lfs_file_locks) do
project.lfs_enabled? && project.lfs_file_locks.any? && newrev && oldrev project.lfs_enabled? && project.lfs_file_locks.any? && newrev && oldrev
end end
end end
private
def lfs_file_locks_validation def lfs_file_locks_validation
lambda do |paths| lambda do |paths|
lfs_lock = project.lfs_file_locks.where(path: paths).where.not(user_id: user.id).first lfs_lock = project.lfs_file_locks.where(path: paths).where.not(user_id: user.id).first
......
...@@ -260,7 +260,7 @@ describe Gitlab::Checks::ChangeAccess do ...@@ -260,7 +260,7 @@ describe Gitlab::Checks::ChangeAccess do
context 'with LFS not enabled' do context 'with LFS not enabled' do
it 'skips the validation' do it 'skips the validation' do
expect_any_instance_of(described_class).not_to receive(:lfs_file_locks_validation) expect_any_instance_of(Gitlab::Checks::CommitCheck).not_to receive(:validate)
subject.exec subject.exec
end end
...@@ -277,7 +277,7 @@ describe Gitlab::Checks::ChangeAccess do ...@@ -277,7 +277,7 @@ describe Gitlab::Checks::ChangeAccess do
end end
end end
context 'when change is sent by the author od the lock' do context 'when change is sent by the author of the lock' do
let(:user) { owner } let(:user) { owner }
it "doesn't raise any error" do it "doesn't raise any error" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment