Force a full GC after importing a project

During a project import, it's possible that new branches are created by
the importer to handle pull requests that have been created from forked
projects, which would increment the `pushes_since_gc` value via
`HousekeepingService.increment!` before a full garbage collection gets
to run. This causes HousekeepingService to skip the full `git gc` and
move to the incremental repack mode. To ensure that a garbage collection
is run to pack refs and objects, explicitly execute the task.

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/59477
This commit is contained in:
Stan Hu 2019-03-31 06:38:23 -07:00 committed by Douglas Barbosa Alexandre
parent 8813447c6f
commit d4c6a3af78
No known key found for this signature in database
GPG key ID: F1E98EF6393565A0
5 changed files with 24 additions and 3 deletions

View file

@ -9,7 +9,7 @@ module Projects
end
def execute
Projects::HousekeepingService.new(@project).execute do
Projects::HousekeepingService.new(@project, :gc).execute do
repository.delete_all_refs_except(RESERVED_REF_PREFIXES)
end
rescue Projects::HousekeepingService::LeaseTaken => e

View file

@ -18,8 +18,9 @@ module Projects
end
end
def initialize(project)
def initialize(project, task = nil)
@project = project
@task = task
end
def execute
@ -69,6 +70,8 @@ module Projects
end
def task
return @task if @task
if pushes_since_gc % gc_period == 0
:gc
elsif pushes_since_gc % full_repack_period == 0

View file

@ -0,0 +1,5 @@
---
title: Force a full GC after importing a project
merge_request: 26803
author:
type: performance

View file

@ -13,7 +13,7 @@ describe Projects::AfterImportService do
describe '#execute' do
before do
allow(Projects::HousekeepingService)
.to receive(:new).with(project).and_return(housekeeping_service)
.to receive(:new).with(project, :gc).and_return(housekeeping_service)
allow(housekeeping_service)
.to receive(:execute).and_yield

View file

@ -88,6 +88,19 @@ describe Projects::HousekeepingService do
expect(project.pushes_since_gc).to eq(1)
end
end
it 'runs the task specifically requested' do
housekeeping = described_class.new(project, :gc)
allow(housekeeping).to receive(:try_obtain_lease).and_return(:gc_uuid)
allow(housekeeping).to receive(:lease_key).and_return(:gc_lease_key)
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :gc_lease_key, :gc_uuid).twice
2.times do
housekeeping.execute
end
end
end
describe '#needed?' do