Skip to content

Instantly share code, notes, and snippets.

@dt1973
Last active August 29, 2015 14:18
Show Gist options
  • Save dt1973/920263906eb7ace5bd74 to your computer and use it in GitHub Desktop.
Save dt1973/920263906eb7ace5bd74 to your computer and use it in GitHub Desktop.

InfiniteInterpolationError

Paperclip model which checks an upload (its temp file) whether it's an animated GIF. If so it sets attachment_is_animated in the db to true. But, because this job needs to go into the background (DelayedJob), the temp file is probably gone by the time it's needed, which is most likely what's causing the InfiniteInterpolationError.


Live app which you can run on the fly: http://runnable.com/VXMNrsiY_6Fd-YRn/paperclip-delayedjob-infiniteinterpolationerror (remember to run bin/delayed_job start before hitting the big green Run button)


app/models/photo.rb

class Photo < ActiveRecord::Base
  belongs_to :post, class_name: "Forem::Post"
  
  attr_accessor :applicable_styles

  has_attached_file :attachment, styles: lambda {
    |attachment| attachment.instance.applicable_styles
  }

  before_post_process :setup_styles
  before_save :set_attachment_is_animated

  ##########
  
  # START DELAYED PAPERCLIP

  process_in_background :attachment

  # Fix conditional styles not being set up in time for `process_in_background`
  
  def applicable_styles
    @applicable_styles || setup_styles
  end

  ##########

  validates_attachment :attachment, presence: true, content_type: {
    content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif", "video/mp4"]
  }

  def attachment_url(style = :medium)
    setup_styles
    style = is_animated_gif? ? "#{style.to_s}_animated".to_sym : style
    attachment.url(style)
  end

  def setup_styles
    @applicable_styles ||= {}

    if is_animated_gif?
    
      # Convert animated GIF to MP4
    
      @applicable_styles[:medium_animated] = {
          format: "mp4",
          streaming: true,
          processors: [:ffmpeg, :qtfaststart]
      }
      @applicable_styles[:thumbnail_animated] = {
          format: "png",
          time: 0.1,
          processors: [:ffmpeg]
      }
    else
    
      # Process as regular photos
    
      @applicable_styles[:medium] = "480x"
      @applicable_styles[:thumbnail] = "50x50#"
    end

    @applicable_styles
  end

  private

  def is_animated_gif?
    attachment_path = attachment.queued_for_write[:original] ? attachment.queued_for_write[:original].path : attachment.path
    rmagick = Magick::ImageList.new(attachment_path)
    attachment.content_type =~ /gif/ && rmagick.scene > 1
  end

  def set_attachment_is_animated
    self.attachment_is_animated = is_animated_gif?
  end
end

rails console

irb(main):001:0> Delayed::Job.all
irb(main):002:0> Delayed::Job.find("1").last_error

Paperclip::Errors::InfiniteInterpolationError
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:53:in `url'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:34:in `block (2 levels) in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `gsub'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `block in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `each'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `inject'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:546:in `interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:166:in `path'
/usr/home/myapp/app/models/photo.rb:58:in `is_animated_gif?'
/usr/home/myapp/app/models/photo.rb:36:in `setup_styles'
/usr/home/myapp/app/models/photo.rb:6:in `applicable_styles'
/usr/home/myapp/app/models/photo.rb:10:in `block in <class:Photo>'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:200:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:200:in `styles'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:100:in `extension'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:45:in `filename'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:34:in `block (2 levels) in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `gsub'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `block in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `each'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `inject'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_paperclip-2.9.1/lib/delayed_paperclip/url_generator.rb:16:in `for_with_processed'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:143:in `url'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:54:in `url'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:34:in `block (2 levels) in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `gsub'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `block in interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `each'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `inject'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:546:in `interpolate'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:166:in `path'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/storage/filesystem.rb:85:in `copy_to_local_file'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/io_adapters/attachment_adapter.rb:27:in `copy_to_tempfile'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/io_adapters/attachment_adapter.rb:19:in `cache_current_values'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/io_adapters/attachment_adapter.rb:11:in `initialize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/io_adapters/registry.rb:29:in `new'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/io_adapters/registry.rb:29:in `for'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:97:in `assign'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:337:in `reprocess!'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_paperclip-2.9.1/lib/delayed_paperclip/attachment.rb:62:in `process_delayed!'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_paperclip-2.9.1/lib/delayed_paperclip.rb:36:in `process_job'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_paperclip-2.9.1/lib/delayed_paperclip/jobs/active_job.rb:12:in `perform'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/execution.rb:32:in `block in perform_now'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:338:in `block (2 levels) in simple'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:23:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:23:in `block (4 levels) in <module:Logging>'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `block in instrument'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `instrument'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:22:in `block (3 levels) in <module:Logging>'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:43:in `block in tag_logger'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/tagged_logging.rb:68:in `block in tagged'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/tagged_logging.rb:26:in `tagged'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/tagged_logging.rb:68:in `tagged'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:43:in `tag_logger'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/logging.rb:19:in `block (2 levels) in <module:Logging>'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:436:in `instance_exec'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:436:in `block in make_lambda'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:337:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:337:in `block in simple'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `_run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:734:in `_run_perform_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:81:in `run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/execution.rb:31:in `perform_now'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/execution.rb:21:in `execute'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.0/lib/active_job/queue_adapters/delayed_job_adapter.rb:34:in `perform'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/backend/base.rb:94:in `block in invoke_job'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/backend/base.rb:91:in `invoke_job'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:204:in `block (2 levels) in run'
/usr/local/lib/ruby/2.2.0/timeout.rb:89:in `block in timeout'
/usr/local/lib/ruby/2.2.0/timeout.rb:99:in `call'
/usr/local/lib/ruby/2.2.0/timeout.rb:99:in `timeout'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:204:in `block in run'
/usr/local/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:203:in `run'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:280:in `block in reserve_and_run_one_job'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:280:in `reserve_and_run_one_job'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:187:in `block in work_off'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:186:in `times'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:186:in `work_off'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:150:in `block (4 levels) in start'
/usr/local/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:149:in `block (3 levels) in start'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:148:in `block (2 levels) in start'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:147:in `loop'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:147:in `block in start'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/plugins/clear_locks.rb:7:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/plugins/clear_locks.rb:7:in `block (2 levels) in <class:ClearLocks>'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `block (2 levels) in add'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `block in add'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/worker.rb:146:in `start'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:124:in `run'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:112:in `block in run_process'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/application.rb:265:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/application.rb:265:in `block in start_proc'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/daemonize.rb:84:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/daemonize.rb:84:in `call_as_daemon'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/application.rb:269:in `start_proc'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/application.rb:295:in `start'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/controller.rb:56:in `run'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons.rb:193:in `block in run_proc'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/cmdline.rb:88:in `call'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons/cmdline.rb:88:in `catch_exceptions'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/daemons-1.2.2/lib/daemons.rb:192:in `run_proc'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:110:in `run_process'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:91:in `block in daemonize'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:89:in `times'
/usr/home/myapp/vendor/bundle/ruby/2.2.0/gems/delayed_job-4.0.6/lib/delayed/command.rb:89:in `daemonize'
bin/delayed_job:5:in `<main>'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment