diff options
author | Jan Provaznik <jprovaznik@gitlab.com> | 2018-12-04 20:48:21 +0100 |
---|---|---|
committer | Jan Provaznik <jprovaznik@gitlab.com> | 2018-12-06 22:00:19 +0100 |
commit | 9ccf8d032ff82841cdfe96e2abe4b1d317058244 (patch) | |
tree | 979a29a1ed7bc6cab4efb578d2b34daafe70f38e | |
parent | 239fdc78b1ced1861cdcf00b8927963e30ef2095 (diff) | |
download | gitlab-ce-9ccf8d032ff82841cdfe96e2abe4b1d317058244.tar.gz |
Enabled feature flag for fast deletions
Fast destroy is used only if the feature flag is enabled, otherwise
uploads are still deleted using carrier wave. It's disabled by default.
-rw-r--r-- | app/models/concerns/with_uploads.rb | 35 | ||||
-rw-r--r-- | app/models/uploads/local.rb | 2 | ||||
-rw-r--r-- | changelogs/unreleased/fast-upload-delete.yml | 5 | ||||
-rw-r--r-- | spec/support/shared_examples/models/with_uploads_shared_examples.rb | 20 |
4 files changed, 55 insertions, 7 deletions
diff --git a/app/models/concerns/with_uploads.rb b/app/models/concerns/with_uploads.rb index 50a9b19299a..761b40893b4 100644 --- a/app/models/concerns/with_uploads.rb +++ b/app/models/concerns/with_uploads.rb @@ -18,6 +18,7 @@ module WithUploads extend ActiveSupport::Concern include FastDestroyAll::Helpers + include FeatureGate # Currently there is no simple way how to select only not-mounted # uploads, it should be all FileUploaders so we select them by @@ -26,12 +27,44 @@ module WithUploads included do has_many :uploads, as: :model - has_many :file_uploads, -> { where(uploader: FILE_UPLOADERS) }, class_name: 'Upload', as: :model, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent + has_many :file_uploads, -> { where(uploader: FILE_UPLOADERS) }, class_name: 'Upload', as: :model + + # TODO: when feature flag is removed, we can use just dependent: destroy + # option on :file_uploads + before_destroy :remove_file_uploads use_fast_destroy :file_uploads end + def perform_fast_destroy(subject) + super if fast_destroy_enabled? + end + def retrieve_upload(_identifier, paths) uploads.find_by(path: paths) end + + private + + # mounted uploads are deleted in carrierwave's after_commit hook, + # but FileUploaders which are not mounted must be deleted explicitly and + # it can not be done in after_commit because FileUploader requires loads + # associated model on destroy (which is already deleted in after_commit) + def remove_file_uploads + fast_destroy_enabled? ? delete_uploads : destroy_uploads + end + + def delete_uploads + file_uploads.delete_all(:delete_all) + end + + def destroy_uploads + file_uploads.find_each do |upload| + upload.destroy + end + end + + def fast_destroy_enabled? + Feature.enabled?(:fast_destroy_uploads, self) + end end diff --git a/app/models/uploads/local.rb b/app/models/uploads/local.rb index ffbf840a9d2..2901c33c359 100644 --- a/app/models/uploads/local.rb +++ b/app/models/uploads/local.rb @@ -3,7 +3,7 @@ module Uploads class Local < Base def keys(relation) - relation.includes(:model).find_each.map {|u| u.absolute_path } + relation.includes(:model).find_each.map(&:absolute_path) end def delete_keys(keys) diff --git a/changelogs/unreleased/fast-upload-delete.yml b/changelogs/unreleased/fast-upload-delete.yml deleted file mode 100644 index c4a85624aa0..00000000000 --- a/changelogs/unreleased/fast-upload-delete.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Delete file uploads asynchronously when deleting a project or other resources. -merge_request: 20977 -author: -type: added diff --git a/spec/support/shared_examples/models/with_uploads_shared_examples.rb b/spec/support/shared_examples/models/with_uploads_shared_examples.rb index 43033a2d256..1d11b855459 100644 --- a/spec/support/shared_examples/models/with_uploads_shared_examples.rb +++ b/spec/support/shared_examples/models/with_uploads_shared_examples.rb @@ -44,6 +44,26 @@ shared_examples_for 'model with uploads' do |supports_fileuploads| model_object.destroy end end + + describe 'destroy strategy depending on feature flag' do + let!(:upload) { create(:upload, uploader: FileUploader, model: model_object) } + + it 'does not destroy uploads by default' do + expect(model_object).to receive(:delete_uploads) + expect(model_object).not_to receive(:destroy_uploads) + + model_object.destroy + end + + it 'uses before destroy callback if feature flag is disabled' do + stub_feature_flags(fast_destroy_uploads: false) + + expect(model_object).to receive(:destroy_uploads) + expect(model_object).not_to receive(:delete_uploads) + + model_object.destroy + end + end end end end |