diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-19 12:10:32 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-19 12:10:32 +0300 |
commit | fcef382cb994b8ecdbff75490bab0425a35f2641 (patch) | |
tree | 1789e9bbda6c4beea4451feb7970705296787445 /app/services/repositories | |
parent | b8f44765693d6f6e4c8df6ab7b7c7b1141f83b26 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/repositories')
-rw-r--r-- | app/services/repositories/housekeeping_service.rb | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/app/services/repositories/housekeeping_service.rb b/app/services/repositories/housekeeping_service.rb new file mode 100644 index 00000000000..6a2fa95d25f --- /dev/null +++ b/app/services/repositories/housekeeping_service.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +# Used for git housekeeping +# +# Ex. +# Repositories::HousekeepingService.new(project).execute +# Repositories::HousekeepingService.new(project.wiki).execute +# +module Repositories + class HousekeepingService < BaseService + # Timeout set to 24h + LEASE_TIMEOUT = 86400 + PACK_REFS_PERIOD = 6 + + class LeaseTaken < StandardError + def to_s + "Somebody already triggered housekeeping for this resource in the past #{LEASE_TIMEOUT / 60} minutes" + end + end + + def initialize(resource, task = nil) + @resource = resource + @task = task + end + + def execute + lease_uuid = try_obtain_lease + raise LeaseTaken unless lease_uuid.present? + + yield if block_given? + + execute_gitlab_shell_gc(lease_uuid) + end + + def needed? + pushes_since_gc > 0 && period_match? && housekeeping_enabled? + end + + def increment! + Gitlab::Metrics.measure(:increment_pushes_since_gc) do + @resource.increment_pushes_since_gc + end + end + + private + + def execute_gitlab_shell_gc(lease_uuid) + GitGarbageCollectWorker.perform_async(@resource.id, task, lease_key, lease_uuid) + ensure + if pushes_since_gc >= gc_period + Gitlab::Metrics.measure(:reset_pushes_since_gc) do + @resource.reset_pushes_since_gc + end + end + end + + def try_obtain_lease + Gitlab::Metrics.measure(:obtain_housekeeping_lease) do + lease = ::Gitlab::ExclusiveLease.new(lease_key, timeout: LEASE_TIMEOUT) + lease.try_obtain + end + end + + def lease_key + "#{@resource.class.name.underscore.pluralize}_housekeeping:#{@resource.id}" + end + + def pushes_since_gc + @resource.pushes_since_gc + end + + def task + return @task if @task + + if pushes_since_gc % gc_period == 0 + :gc + elsif pushes_since_gc % full_repack_period == 0 + :full_repack + elsif pushes_since_gc % repack_period == 0 + :incremental_repack + else + :pack_refs + end + end + + def period_match? + [gc_period, full_repack_period, repack_period, PACK_REFS_PERIOD].any? { |period| pushes_since_gc % period == 0 } + end + + def housekeeping_enabled? + Gitlab::CurrentSettings.housekeeping_enabled + end + + def gc_period + Gitlab::CurrentSettings.housekeeping_gc_period + end + + def full_repack_period + Gitlab::CurrentSettings.housekeeping_full_repack_period + end + + def repack_period + Gitlab::CurrentSettings.housekeeping_incremental_repack_period + end + end +end |