Очистить кэшированные изображения Shrine при сохранении успеха

Фон
Я использую хранилище файловой системы с модулем Shrine :: Attachment в модель (my_model) с activerecord (Rails). Я также использую его в сценарии прямой загрузки, поэтому мне нужен ответ от загрузки файла (сохранение в кеш).

my_model.rb

class MyModel < ApplicationRecord
   include ImageUploader::Attachment(:image) # adds an `image` virtual attribute
   omitted relations & code...
end

my_controller.rb

def create
  @my_model = MyModel.new(my_model_params)
  # currently creating derivatives & persisting all in one go
  @my_model.image_derivatives! if @my_model.image 

  if @my_model.save
    render json: { success: "MyModel created successfully!" }
  else
    @errors = @my_model.errors.messages
    render 'errors', status: :unprocessable_entity
  end

Цель
В идеале я хочу очистить только кэшированные файлы, которые у меня есть в моем контроллере создания, как только они будут сохранены (производные и исходный файл) в постоянном хранилище.
Как лучше всего это сделать для сценария A: синхронного и сценария B: асинхронного?

Что я рассмотрел / попробовал
Прочитав документы, я заметил 3 возможных способа очистки кешированных изображений:
1. Запустите rake task для очистки кешированных изображений.

Мне это действительно не нравится, поскольку я считаю, что кешированные файлы должны быть очищены после того, как файл был сохранен, а не оставлен как задача администратора (задание cron), которое нельзя протестировать со спецификацией сохранения изображения

# FileSystem storage file_system = Shrine.storages[:cache] file_system.clear! { |path| path.mtime < Time.now - 7*24*60*60 } # delete files older than 1 week

2. Запустите Shrine.storages [: cache] в после блока

Это только для фоновых заданий?

attacher.atomic_persist do |reloaded_attacher| # run code after attachment change check but before persistence end

3. Переместить файл кеша в постоянное хранилище

Я не думаю, что смогу использовать это, поскольку моя прямая загрузка происходит в двух разных частях: 1, немедленно загружаю прикрепленный файл в кешированное хранилище, затем 2, сохраняю его во вновь созданной записи.
plugin :upload_options, cache: { move: true }, store: { move: true }

Есть ли более эффективные способы очистки продвигаемых изображений из кеша для моих нужд?


person orion    schedule 13.12.2019    source источник
comment
Если вы настроили автоматическое удаление кэшированных файлов после того, как они переведены в постоянное хранилище, вам по-прежнему не гарантируется отсутствие кешированных файлов в рабочей среде. Это связано с тем, что не все файлы, загруженные во временное хранилище, могут быть прикреплены. Если в форме есть ошибки проверки, пользователь может передумать и загрузить другое изображение, и в этом случае исходное изображение не было прикреплено. То же самое может случиться и с прямой загрузкой.   -  person janko-m    schedule 07.01.2020


Ответы (1)


Синхронное решение для случая загрузки одного изображения:

def create
  @my_model = MyModel.new(my_model_params)
  image_attacher = @my_model.image_attacher               
  image_attacher.create_derivatives                       # Create different sized images
  image_cache_id = image_attacher.file.id                 # save image cache file id as it will be lost in the next step
  image_attacher.record.save(validate: true)              # Promote original file to permanent storage
  Shrine.storages[:cache].delete(image_cache_id)  # Only clear cached image that was used to create derivatives (if other images are being processed and are cached we dont want to blow them away)
end
person orion    schedule 13.12.2019
comment
Обратите внимание, что вы можете упростить код следующим образом: cached_image = image_attacher.file, а затем выполните cached_image.delete. - person janko-m; 07.01.2020