Challenge 2: Retry and Discard — Solution # app/jobs/resize_image_job.rb class ResizeImageJob < ApplicationJob queue_as :default retry_on ImageProcessingTimeout, wait: :exponentially_longer, attempts: 3 discard_on ActiveRecord::RecordNotFound def perform(image_id) image = Image.find(image_id) image.resize! end end =begin Notes: - retry_on ImageProcessingTimeout treats a timeout as transient -- whatever caused the resize to take too long (a busy processing service, a temporarily large file) is worth trying again for, so the job retries up to 3 times with wait: :exponentially_longer spacing retries further apart each time rather than hammering the same failure immediately. - discard_on ActiveRecord::RecordNotFound is the opposite judgment call: if the image was deleted before the job ran, no number of retries fixes that, so the job gives up on the first attempt instead of retrying a failure that can never succeed. - Both declarations sit above perform, matching where queue_as already lives -- job-level configuration, separate from the actual work the job does. =end