ruby 27 lines · 7 steps

Purging stale exports with an Active Job in Rails

A Rails background job batch-deletes old exports and their attachments, with retry policies and a rake task to enqueue it.

Explained by highlit
1class PurgeStaleExportsJob < ApplicationJob
2 queue_as :maintenance
3 
4 retry_on ActiveRecord::Deadlocked, wait: :polynomially_longer, attempts: 5
5 retry_on Aws::S3::Errors::ServiceError, wait: 30.seconds, attempts: 3
6 discard_on ActiveJob::DeserializationError
7 
8 RETENTION = 7.days
9 
10 def perform(older_than: RETENTION.ago)
11 Export.completed.where(created_at: ..older_than).in_batches(of: 200) do |batch|
12 batch.each do |export|
13 export.file.purge_later if export.file.attached?
14 end
15 
16 deleted = batch.delete_all
17 Rails.logger.info("[PurgeStaleExports] removed #{deleted} exports")
18 end
19 end
20end
21 
22namespace :exports do
23 desc "Enqueue cleanup of stale exports (run hourly via cron/whenever)"
24 task cleanup: :environment do
25 PurgeStaleExportsJob.perform_later
26 end
27end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Processing records in batches keeps memory bounded and avoids locking huge row sets at once.
  2. 2Declarative retry_on and discard_on rules let a job tolerate transient failures without custom rescue logic.
  3. 3Purging attachments separately from deleting rows prevents orphaned files in your storage backend.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Purging stale exports with an Active Job in Rails — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code