ruby 31 lines · 8 steps

Resilient background jobs with retry_on in Rails

An ActiveJob that syncs supplier inventory, retrying transient failures and discarding unrecoverable ones.

Explained by highlit
1class SyncInventoryJob < ApplicationJob
2 queue_as :integrations
3 
4 retry_on Faraday::TimeoutError,
5 Faraday::ConnectionFailed,
6 SupplierClient::RateLimited,
7 wait: :polynomially_longer,
8 attempts: 6,
9 jitter: 0.3
10 
11 discard_on ActiveRecord::RecordNotFound
12 discard_on SupplierClient::UnknownSku
13 
14 def perform(product_id)
15 product = Product.find(product_id)
16 client = SupplierClient.new(product.supplier)
17 
18 snapshot = client.fetch_inventory(sku: product.sku)
19 
20 product.update!(
21 stock_quantity: snapshot.available,
22 backorderable: snapshot.backorderable?,
23 inventory_synced_at: Time.current
24 )
25 
26 LowStockNotifier.check(product) if snapshot.available <= product.low_stock_threshold
27 rescue SupplierClient::AuthenticationError => e
28 IntegrationAlert.raise!(product.supplier, error: e)
29 raise
30 end
31end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Separate transient errors (retry) from permanent ones (discard) so the queue self-heals without piling up doomed work.
  2. 2Exponential backoff with jitter spreads retries out and avoids hammering a struggling upstream service.
  3. 3Rescue-and-re-raise lets you alert on a specific failure while still letting the job's retry machinery run.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Resilient background jobs with retry_on in Rails — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code