2013-07-30 10 views
2

Я по существу записываю проект в Railscast 383 - вторая часть, когда фотография загружается непосредственно в AWS S3, а затем фотография обрабатывается в фоновом режиме Sidekiq для создания миниатюрной версии фотографии. Я на Rails 4.Sidekiq повторяет ту же работу снова и снова

Моя проблема заключается в том, что работа 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 

ImageWorker:

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 

ответ

1

Одной из причин для sidekiq работника быть вызывается снова и снова, потому что perform_async вызывается каждый раз, когда вы сохраняете свой фотообъект, что происходит внутри самого работника sidekiq. Итак, каждый раз, когда вызывается ImageWorker, он сохраняет фотографию, снова вызывая ImageWorker, создавая цикл, который вы испытываете.

Уверены, что вы не пропустили проверку для тега :image_processed, чтобы быть правдой, прежде чем снова позвонить ImageWorker. Попробуйте это:

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

Это будет проверять, если изображение было обработано однажды. Я думаю, что это, вероятно, предназначалось для установки в рельсах, но автор забыл об этом, иначе флаг image_processed устарел.

Смежные вопросы