# Worker that takes care of creating a snapshot image and comparing that image
# to a previous baseline
class SnapshotWorker
  include Sidekiq::Worker

  def perform(snapshot_id)
    snapshot        = Snapshot.find(snapshot_id)
    url             = snapshot.url
    viewport        = snapshot.viewport
    snapshot_result = Snapshotter.new(url, viewport).take_snapshot!

    snapshot.title             = snapshot_result[:title]
    snapshot.external_image_id = snapshot_result[:external_image_id]

    if baseline = url.baseline(viewport)
      Rails.logger.info "Comparing snapshot of #{url} @ #{viewport} " +
                        'against baseline'
      diff = SnapshotComparer.new(snapshot, baseline).compare!
      snapshot.diff_from_previous     = diff[:diff_in_percent]
      snapshot.diffed_with_snapshot   = baseline
      if diff_image = diff[:diff_image]
        snapshot.diff_external_image_id = FileUtil.upload_png(diff_image)
      end
      snapshot.accept! if snapshot.diff_from_previous == 0
    end

    snapshot.save!
  end
end

# Worker that takes care of creating a snapshot image and comparing that image
# to a previous baseline
class SnapshotWorker
  include Sidekiq::Worker

  def perform(snapshot_id)
    begin
      snapshot = Snapshot.find(snapshot_id)
    rescue ActiveRecord::RecordNotFound
      # The Snapshot was deleted before the worker could run, so there is
      # nothing left for this worker to do.
      return
    end

    url             = snapshot.url
    viewport        = snapshot.viewport
    snapshot_result = Snapshotter.new(url, viewport).take_snapshot!

    snapshot.title             = snapshot_result[:title]
    snapshot.external_image_id = snapshot_result[:external_image_id]

    if baseline = url.baseline(viewport)
      Rails.logger.info "Comparing snapshot of #{url} @ #{viewport} " +
                        'against baseline'
      diff = SnapshotComparer.new(snapshot, baseline).compare!
      snapshot.diff_from_previous     = diff[:diff_in_percent]
      snapshot.diffed_with_snapshot   = baseline
      if diff_image = diff[:diff_image]
        snapshot.diff_external_image_id = FileUtil.upload_png(diff_image)
      end
      snapshot.accept! if snapshot.diff_from_previous == 0
    end

    snapshot.save!
  end
end

Allow SnapshotWorkers that can't find Snapshot to rest in peace
Allow SnapshotWorkers that can't find Snapshot to rest in peace

If you were to create a Snapshot and then delete it before the worker
had the chance to act on it, the work request would stay in the queue,
causing it to be run every time the workers spun up. This could happen
easily, for instance, if there was an unexpected error that prevented
the worker from returning successfully. In fact, this is a problem that
I saw quite often while developing Diffux.

To allow these zombie workers to rest in peace, I am adding a rescue for
the exception that is raised when the record is not found. Because, if
the Snapshot they were supposed to act upon is no longer there, there is
no more work for them to do.

Change-Id: If582e4b27514b5c7783480669db51172b4391c37
