diff options
author | Shinya Maeda <shinya@gitlab.com> | 2019-01-17 15:06:37 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2019-01-24 20:50:42 +0900 |
commit | 3cc3650dfee5132c120b2b418918f12b3eebcde2 (patch) | |
tree | 0497feec4829ed16e0b0d37954b0998a4d8fac15 /app | |
parent | 490eeb5159945107576c756b22c08f99b45a8463 (diff) | |
download | gitlab-ce-3cc3650dfee5132c120b2b418918f12b3eebcde2.tar.gz |
Remove expired artifacts periodically
Rename
Introduce Destroy expired job artifacts service
Revert a bit
Add changelog
Use expired
Improve
Fix spec
Fix spec
Use bang for destroy
Introduce iteration limit
Update comment
Simplify more
Refacor
Remove unnecessary thing
Fix comments
Fix coding offence
Make loop helper exception free
Diffstat (limited to 'app')
-rw-r--r-- | app/models/ci/job_artifact.rb | 2 | ||||
-rw-r--r-- | app/services/ci/destroy_expired_job_artifacts_service.rb | 38 | ||||
-rw-r--r-- | app/workers/expire_build_artifacts_worker.rb | 14 |
3 files changed, 53 insertions, 1 deletions
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index 11c88200c37..789bb293811 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -73,6 +73,8 @@ module Ci where(file_type: types) end + scope :expired, -> (limit) { where('expire_at < ?', Time.now).limit(limit) } + delegate :filename, :exists?, :open, to: :file enum file_type: { diff --git a/app/services/ci/destroy_expired_job_artifacts_service.rb b/app/services/ci/destroy_expired_job_artifacts_service.rb new file mode 100644 index 00000000000..7d2f5d33fed --- /dev/null +++ b/app/services/ci/destroy_expired_job_artifacts_service.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Ci + class DestroyExpiredJobArtifactsService + include ::Gitlab::ExclusiveLeaseHelpers + include ::Gitlab::LoopHelpers + + BATCH_SIZE = 100 + LOOP_TIMEOUT = 45.minutes + LOOP_LIMIT = 1000 + EXCLUSIVE_LOCK_KEY = 'expired_job_artifacts:destroy:lock' + LOCK_TIMEOUT = 50.minutes + + ## + # Destroy expired job artifacts on GitLab instance + # + # This destroy process cannot run for more than 45 minutes. This is for + # preventing multiple `ExpireBuildArtifactsWorker` CRON jobs run concurrently, + # which is scheduled at every hour. + def execute + in_lock(EXCLUSIVE_LOCK_KEY, ttl: LOCK_TIMEOUT, retries: 1) do + loop_until(timeout: LOOP_TIMEOUT, limit: LOOP_LIMIT) do + destroy_batch + end + end + end + + private + + def destroy_batch + artifacts = Ci::JobArtifact.expired(BATCH_SIZE).to_a + + return false if artifacts.empty? + + artifacts.each(&:destroy!) + end + end +end diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb index dce812d1ae2..251e95c68d5 100644 --- a/app/workers/expire_build_artifacts_worker.rb +++ b/app/workers/expire_build_artifacts_worker.rb @@ -4,8 +4,20 @@ class ExpireBuildArtifactsWorker include ApplicationWorker include CronjobQueue - # rubocop: disable CodeReuse/ActiveRecord def perform + if Feature.enabled?(:ci_new_expire_job_artifacts_service, default_enabled: true) + perform_efficient_artifacts_removal + else + perform_legacy_artifacts_removal + end + end + + def perform_efficient_artifacts_removal + Ci::DestroyExpiredJobArtifactsService.new.execute + end + + # rubocop: disable CodeReuse/ActiveRecord + def perform_legacy_artifacts_removal Rails.logger.info 'Scheduling removal of build artifacts' build_ids = Ci::Build.with_expired_artifacts.pluck(:id) |