Carrierwave безопасен для потоков? - PullRequest
0 голосов
/ 29 октября 2018

Я использую Sidekiq и Carrierwave для загрузки изображений в S3. Фоновое задание выполняет следующие действия:

  1. Загрузка изображения с удаленного URL;
  2. Изменение размера с помощью минимагика;
  3. Загрузка изображений с измененным размером на S3.

Вот фрагмент кода:

  def store_for_mobile(file)
     self.class.process optimize: [1080, 810]
     %w(android ios).each do |device|
        @directory = File.join('banners/mobile', device)
        store!(file)
     end
  end

  def store_for_web(file)
     self.class.process optimize: [750, 562]
     @directory = 'stores/750x562/'
     store!(file)
  end

  def store_header(file)
    self.class.process resize_to_limit: [640, 640]
    @directory = 'headers/images/consumer_app_brand_logos/'
    store!(file)
  end

  def store_header_mailer(file)
    self.class.process resize_to_limit: [360, 120]
    @directory = 'headers/images/360x120/'
    store!(file)
  end

Указанные выше методы выполняются в разных заданиях соответственно, что означает, что иногда они выполняются одновременно.

Вскоре я заметил, что некоторые изображения, размер которых был изменен на store_header_mailer, были загружены в каталог, который должен принадлежать store_for_mobile, store_for_web и store_header. (например, 'headers/images/consumer_app_brand_logos/' получено 120x120 изображений)

Этой проблемы не было, пока я использовал Resque.

Я посмотрел на исходный код carrierwave и заметил, что

https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/uploader/processing.rb#L54

он использует переменные класса self.processors и методы класса self.process при вызове командных строк image_magick.

Является ли эта часть кода поточно-ориентированной? Заранее спасибо.

1 Ответ

0 голосов
/ 03 ноября 2018

Потратил несколько дней, чтобы выяснить, что происходит. Это довольно интересный случай, и он слишком длинный, чтобы объяснить его здесь, поэтому я решил написать для него сообщение , поэтому для более подробной информации, пожалуйста, прочитайте его там.


Короче говоря, carrierwave использует переменную класса для сохранения метода и размеров процессора, и он не сбрасывается после завершения загрузки, поэтому будет затронут следующий загрузчик.

...