2

我基本上是在Railscast 383中编写项目- 第二部分,当照片直接上传到 AWS S3 时,然后由 Sidekiq 在后台处理照片以创建照片的缩略图版本。我在 Rails 4 上。

我的问题是 Sidekiq 工作在成功完成后会不断重复,而不是停止。

我哪里错了?我看不出我的代码和 Railscast 的代码有什么区别,除了我在 Rails 4 上(这么强的参数而不是attr_accessible

照片类:

class Photo < ActiveRecord::Base
  mount_uploader :image, ImageUploader

  default_scope order('updated_at DESC')

  after_save :enqueue_image

  def image_name
    File.basename(image.path || image.filename) if image
  end

  def enqueue_image
    ImageWorker.perform_async(id, key) if key.present?
  end
end

图像工作者:

class ImageWorker
  include Sidekiq::Worker

  sidekiq_options retry: false
  # sidekiq_options retry: 3

  def perform(id, key)
    photo = Photo.find(id)
    photo.key = key
    photo.remote_image_url = photo.image.direct_fog_url(with_path: true)
    photo.save!
    photo.update_column(:image_processed, true)
  end
end

上传者:

class ImageUploader < CarrierWave::Uploader::Base

  include CarrierWaveDirect::Uploader
  include CarrierWave::RMagick

  # storage :fog
  #### storage defaults to fog when CarrierWaveDirect::Uploader is included ####

  include CarrierWave::MimeTypes
  process :set_content_type

  version :thumb do
    process :resize_to_limit => [200, 200]
  end

  version :medium do
    process :resize_to_limit => [400, 400]
  end

end
4

1 回答 1

2

一次又一次地调用 sidekiq 工作程序的一个原因是因为perform_async每次保存照片对象时都会调用 ,这发生在 sidekiq 工作程序本身内。因此,每次ImageWorker调用时,它都会保存照片,ImageWorker再次调用,创建您正在经历的循环。

您确定:image_processed在再次调用之前没有错过检查标签是否为真ImageWorker。尝试这个:

def enqueue_image
    ImageWorker.perform_async(id, key) if key.present? && !image_processed
end

这将检查图像之前是否处理过一次。我认为这可能是为了在 rails cast 中设置,但作者忘记了,否则 image_processed 标志已过时。

于 2013-07-30T18:06:42.407 回答