summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Provaznik <jprovaznik@gitlab.com>2018-12-04 20:48:21 +0100
committerJan Provaznik <jprovaznik@gitlab.com>2018-12-06 22:00:19 +0100
commit9ccf8d032ff82841cdfe96e2abe4b1d317058244 (patch)
tree979a29a1ed7bc6cab4efb578d2b34daafe70f38e
parent239fdc78b1ced1861cdcf00b8927963e30ef2095 (diff)
downloadgitlab-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.rb35
-rw-r--r--app/models/uploads/local.rb2
-rw-r--r--changelogs/unreleased/fast-upload-delete.yml5
-rw-r--r--spec/support/shared_examples/models/with_uploads_shared_examples.rb20
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