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.
This commit is contained in:
Jan Provaznik 2018-12-04 20:48:21 +01:00
parent 239fdc78b1
commit 9ccf8d032f
4 changed files with 55 additions and 7 deletions

View file

@ -18,6 +18,7 @@
module WithUploads module WithUploads
extend ActiveSupport::Concern extend ActiveSupport::Concern
include FastDestroyAll::Helpers include FastDestroyAll::Helpers
include FeatureGate
# Currently there is no simple way how to select only not-mounted # Currently there is no simple way how to select only not-mounted
# uploads, it should be all FileUploaders so we select them by # uploads, it should be all FileUploaders so we select them by
@ -26,12 +27,44 @@ module WithUploads
included do included do
has_many :uploads, as: :model 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 use_fast_destroy :file_uploads
end end
def perform_fast_destroy(subject)
super if fast_destroy_enabled?
end
def retrieve_upload(_identifier, paths) def retrieve_upload(_identifier, paths)
uploads.find_by(path: paths) uploads.find_by(path: paths)
end 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 end

View file

@ -3,7 +3,7 @@
module Uploads module Uploads
class Local < Base class Local < Base
def keys(relation) def keys(relation)
relation.includes(:model).find_each.map {|u| u.absolute_path } relation.includes(:model).find_each.map(&:absolute_path)
end end
def delete_keys(keys) def delete_keys(keys)

View file

@ -1,5 +0,0 @@
---
title: Delete file uploads asynchronously when deleting a project or other resources.
merge_request: 20977
author:
type: added

View file

@ -44,6 +44,26 @@ shared_examples_for 'model with uploads' do |supports_fileuploads|
model_object.destroy model_object.destroy
end end
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 end
end end