Stack level too deep when using carrierwave versio

2019-02-08 20:12发布

问题:

I'm trying to use a sidekiq worker, which more or less saves a image file to database (using carrierwave). There are few files to save, which are a keyframes extracted from a video file. That's what that worker is about.

My image uploader has a few versions defined and looks as follows:

class KeyframeUploader < CarrierWave::Uploader::Base

  # ...

  # Keyframe thumbnail sizes
  version :small do
    process resize_to_fill: [180, 180], if: :square?
    process resize_to_fill: [320, 180], if: :not_square?
  end

  version :medium do
    process resize_to_fill: [460, 460], if: :square?
    process resize_to_fill: [640, 460], if: :not_square?
  end

  version :large do
    process resize_to_fill: [720, 720], if: :square?
    process resize_to_fill: [1280, 720], if: :not_square?
  end


  private

    # Checks if image is a square
    def square? file
      img = Magick::Image.read(file.path)
      img[0].columns == img[0].rows
    end

    # Oposite to #square?
    def not_square? file
      !square? file
    end

end

The thing is, when i'm trying to run my Sidekiq Worker, it throws Celluloid::FiberStackError: stack level too deep and the only way to fix that is to remove my version definitions. It works only if there are not any version assigned to the uploader.

I have tried moving a save process to another worker or using Carrierwave::Backgrounder but i'm allways getting the same result.

Have you any idea what can i do about it?


Edit: My stracktrace is:

SystemStackError: stack level too deep from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/irb/workspace.rb:86

回答1:

It turned out, that it's a carrierwave's fault (well, actually, osx fault). Thread with explanation: https://github.com/carrierwaveuploader/carrierwave/issues/1330

Solution:

gem 'rmagick', :require => 'RMagick'


回答2:

i would target the for loop in your worker.

for i in 1..(frames_to_extract)

you're not incrementing i but you seem to be doing an indexed loop. I would switch it to use enum and each_with_index.

Rubyists tend to avoid the for loop as its a nasty mess.



回答3:

  1. check your models, see if you have got an after_save hook for example which would regress into an infinite loop if you update the record in that hook - it's possible you've got an after_save which creates the job to make thumbnails and then storing those thumbnails initiates another job
  2. check for thread-safety issues, are any of the gems you are using listed here
  3. check your stack trace, can you see which lines are repeating?
  4. is the error present when you're not using sidekiq to process the files?
  5. does the problem happen always or just under load?
  6. RMagick bug with Ruby 2.1 - https://github.com/rmagick/rmagick/issues/100
  7. ...