summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2019-05-22 10:47:43 +0000
committerNick Thomas <nick@gitlab.com>2019-05-22 10:47:43 +0000
commit3846f89d4f9164e16313c11a78bdf9fa3ee2294e (patch)
tree0097a09513f561fa011197a6c7115c5db0c3c48f /app
parent3fc64f38e7fbebe917c2a82156ccf2612d65e9e0 (diff)
parent6c35fb59b79e7abc321cee65fc1730ce67908b6b (diff)
downloadgitlab-ce-3846f89d4f9164e16313c11a78bdf9fa3ee2294e.tar.gz
Merge branch 'jc-git-deduplication-service' into 'master'
Add GitDeduplicationService Closes #60871 See merge request gitlab-org/gitlab-ce!28144
Diffstat (limited to 'app')
-rw-r--r--app/services/projects/git_deduplication_service.rb64
-rw-r--r--app/workers/git_garbage_collect_worker.rb4
2 files changed, 67 insertions, 1 deletions
diff --git a/app/services/projects/git_deduplication_service.rb b/app/services/projects/git_deduplication_service.rb
new file mode 100644
index 00000000000..74d469ecf37
--- /dev/null
+++ b/app/services/projects/git_deduplication_service.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Projects
+ class GitDeduplicationService < BaseService
+ include ExclusiveLeaseGuard
+
+ LEASE_TIMEOUT = 86400
+
+ delegate :pool_repository, to: :project
+ attr_reader :project
+
+ def initialize(project)
+ @project = project
+ end
+
+ def execute
+ try_obtain_lease do
+ unless project.has_pool_repository?
+ disconnect_git_alternates
+ break
+ end
+
+ if source_project? && pool_can_fetch_from_source?
+ fetch_from_source
+ end
+
+ project.link_pool_repository if same_storage_as_pool?(project.repository)
+ end
+ end
+
+ private
+
+ def disconnect_git_alternates
+ project.repository.disconnect_alternates
+ end
+
+ def pool_can_fetch_from_source?
+ project.git_objects_poolable? &&
+ same_storage_as_pool?(pool_repository.source_project.repository)
+ end
+
+ def same_storage_as_pool?(repository)
+ pool_repository.object_pool.repository.storage == repository.storage
+ end
+
+ def fetch_from_source
+ project.pool_repository.object_pool.fetch
+ end
+
+ def source_project?
+ return unless project.has_pool_repository?
+
+ project.pool_repository.source_project == project
+ end
+
+ def lease_timeout
+ LEASE_TIMEOUT
+ end
+
+ def lease_key
+ "git_deduplication:#{project.id}"
+ end
+ end
+end
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index d4a6f53dae5..489d6215774 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -23,7 +23,9 @@ class GitGarbageCollectWorker
end
task = task.to_sym
- project.link_pool_repository
+
+ ::Projects::GitDeduplicationService.new(project).execute
+
gitaly_call(task, project.repository.raw_repository)
# Refresh the branch cache in case garbage collection caused a ref lookup to fail