Commit 89d3ef38 authored by Yorick Peterse's avatar Yorick Peterse

Schedule at most 100 commits

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
parent 5c0f2541
...@@ -3,6 +3,9 @@ class GitPushService < BaseService ...@@ -3,6 +3,9 @@ class GitPushService < BaseService
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
include Gitlab::Access 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 # This method will be called after each git update
# and only if the provided user and project are present in GitLab. # and only if the provided user and project are present in GitLab.
# #
...@@ -77,6 +80,16 @@ class GitPushService < BaseService ...@@ -77,6 +80,16 @@ class GitPushService < BaseService
ProjectCacheWorker.perform_async(@project.id, types) ProjectCacheWorker.perform_async(@project.id, types)
end 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 protected
def execute_related_hooks def execute_related_hooks
...@@ -128,17 +141,6 @@ class GitPushService < BaseService ...@@ -128,17 +141,6 @@ class GitPushService < BaseService
end end
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 def build_push_data
@push_data ||= Gitlab::DataBuilder::Push.build( @push_data ||= Gitlab::DataBuilder::Push.build(
@project, @project,
......
---
title: Push payloads schedule at most 100 commits, instead of all commits
merge_request:
author:
...@@ -604,6 +604,25 @@ describe GitPushService, services: true do ...@@ -604,6 +604,25 @@ describe GitPushService, services: true do
end end
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) def execute_service(project, user, oldrev, newrev, ref)
service = described_class.new(project, user, oldrev: oldrev, newrev: newrev, ref: ref ) service = described_class.new(project, user, oldrev: oldrev, newrev: newrev, ref: ref )
service.execute service.execute
......
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