summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2016-12-21 16:26:35 +0100
committerYorick Peterse <yorickpeterse@gmail.com>2016-12-23 14:05:00 +0100
commit89d3ef38ccc7be722a0906d08b51a48b1c8ff681 (patch)
treede90aa1c24d32dfefcc95872f09817e5e8cf6cb1
parent5c0f25410cb2b94642d03361565372ceb5e14c00 (diff)
downloadgitlab-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.rb24
-rw-r--r--changelogs/unreleased/process-commit-worker-large-batches.yml4
-rw-r--r--spec/services/git_push_service_spec.rb19
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