diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2016-12-21 16:26:35 +0100 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2016-12-23 14:05:00 +0100 |
commit | 89d3ef38ccc7be722a0906d08b51a48b1c8ff681 (patch) | |
tree | de90aa1c24d32dfefcc95872f09817e5e8cf6cb1 | |
parent | 5c0f25410cb2b94642d03361565372ceb5e14c00 (diff) | |
download | gitlab-ce-process-commit-worker-large-batches.tar.gz |
Schedule at most 100 commitsprocess-commit-worker-large-batches
When processing push payloads we now schedule at most the 100 most
recent commits, instead of all commits that were in a payload. This
prevents one from overloading the system by pushing thousands if not
millions of commits in a single go.
Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/25827
-rw-r--r-- | app/services/git_push_service.rb | 24 | ||||
-rw-r--r-- | changelogs/unreleased/process-commit-worker-large-batches.yml | 4 | ||||
-rw-r--r-- | spec/services/git_push_service_spec.rb | 19 |
3 files changed, 36 insertions, 11 deletions
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 185556c12cc..6bbc3a9d9ff 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -3,6 +3,9 @@ class GitPushService < BaseService include Gitlab::CurrentSettings include Gitlab::Access + # The N most recent commits to process in a single push payload. + PROCESS_COMMIT_LIMIT = 100 + # This method will be called after each git update # and only if the provided user and project are present in GitLab. # @@ -77,6 +80,16 @@ class GitPushService < BaseService ProjectCacheWorker.perform_async(@project.id, types) end + # Schedules processing of commit messages. + def process_commit_messages + default = is_default_branch? + + push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit| + ProcessCommitWorker. + perform_async(project.id, current_user.id, commit.to_hash, default) + end + end + protected def execute_related_hooks @@ -128,17 +141,6 @@ class GitPushService < BaseService end end - # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, - # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. - def process_commit_messages - default = is_default_branch? - - @push_commits.each do |commit| - ProcessCommitWorker. - perform_async(project.id, current_user.id, commit.to_hash, default) - end - end - def build_push_data @push_data ||= Gitlab::DataBuilder::Push.build( @project, diff --git a/changelogs/unreleased/process-commit-worker-large-batches.yml b/changelogs/unreleased/process-commit-worker-large-batches.yml new file mode 100644 index 00000000000..6fa31b62e4a --- /dev/null +++ b/changelogs/unreleased/process-commit-worker-large-batches.yml @@ -0,0 +1,4 @@ +--- +title: Push payloads schedule at most 100 commits, instead of all commits +merge_request: +author: diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index e7624e70725..3303e808a9c 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -604,6 +604,25 @@ describe GitPushService, services: true do end end + describe '#process_commit_messages' do + let(:service) do + described_class.new(project, + user, + oldrev: sample_commit.parent_id, + newrev: sample_commit.id, + ref: 'refs/heads/master') + end + + it 'only schedules a limited number of commits' do + allow(service).to receive(:push_commits). + and_return(Array.new(1000, double(:commit, to_hash: {}))) + + expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times + + service.process_commit_messages + end + end + def execute_service(project, user, oldrev, newrev, ref) service = described_class.new(project, user, oldrev: oldrev, newrev: newrev, ref: ref ) service.execute |