ruby - Carrierwave 是线程安全的吗?
问题描述
我正在使用 Sidekiq 和 Carrierwave 将图像上传到 S3。后台作业执行以下操作:
- 从远程 url 下载图像;
- 使用 minimagick 调整大小;
- 将调整大小的图像上传到 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_web
store_header
'headers/images/consumer_app_brand_logos/'
这个问题在我使用 Resque 时不存在。
我查看了carrierwave的源代码,并注意到
它在调用 image_magick 命令行时使用类变量self.processors
和类方法。self.process
这部分代码是线程安全的吗?提前致谢。
解决方案
花了几天时间弄清楚发生了什么事。这是一个有趣的案例,在这里解释也太长了,所以我决定为它写一篇文章,所以有关更多详细信息,请在此处阅读。
长话短说,carrierwave 使用类变量来保存处理器方法和尺寸,并且在上传者完成后不会重置,因此会影响下一个上传者。
推荐阅读
- android - 防止或避免 Android 应用程序中的多次点击(Kotlin 语言)
- php - 如果 Laravel 类别中没有帖子,则重定向
- mongodb - 如何在mongoDB聚合中按字符串模式(不一定是正则表达式)分组
- angular - 如何在 URL 中传递变量,同时从 Angular 后端获取数据?
- c# - 为什么当我打开 WPF .core 项目但可用于 .net 项目时,MS blend 2019 中缺少触发器选项卡?
- bash - 如何在 bash 中实现重试功能?
- c - 在终端中执行用户输入文件时拒绝 VS 代码访问
- sql - 使用 SQL 填写日期
- python - Windows 命令提示符 - 无法识别 nnictl 命令
- c# - 如何从另一个类/文件中引用使用别名指令