首页 > 解决方案 > Carrierwave 是线程安全的吗?

问题描述

我正在使用 Sidekiq 和 Carrierwave 将图像上传到 S3。后台作业执行以下操作:

  1. 从远程 url 下载图像;
  2. 使用 minimagick 调整大小;
  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中。(例如得到 120x120 的图像)store_for_webstore_header'headers/images/consumer_app_brand_logos/'

这个问题在我使用 Resque 时不存在。

我查看了carrierwave的源代码,并注意到

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

它在调用 image_magick 命令行时使用类变量self.processors和类方法。self.process

这部分代码是线程安全的吗?提前致谢。

标签: rubycarrierwavesidekiq

解决方案


花了几天时间弄清楚发生了什么事。这是一个有趣的案例,在这里解释也太长了,所以我决定为它写一篇文章,所以有关更多详细信息,请在此处阅读。


长话短说,carrierwave 使用类变量来保存处理器方法和尺寸,并且在上传者完成后不会重置,因此会影响下一个上传者。


推荐阅读