rails-jobs-patterns
4
总安装量
2
周安装量
#54276
全站排名
安装命令
npx skills add https://github.com/ag0os/rails-dev-plugin --skill rails-jobs-patterns
Agent 安装分布
cursor
2
windsurf
1
Skill 文档
Rails Background Job Patterns
Patterns for building reliable, efficient background jobs in Rails applications.
When This Skill Applies
- Creating background jobs with ActiveJob
- Configuring Sidekiq queues and workers
- Implementing idempotent job patterns
- Error handling and retry strategies
- Batch processing large datasets
- Scheduling recurring jobs
Core Principles
Idempotency
Jobs should be safe to run multiple times:
def perform(order_id)
order = Order.find(order_id)
return if order.processed? # Guard against re-processing
order.with_lock do
return if order.processed?
process_order(order)
order.update!(status: 'processed')
end
end
Small, Focused Jobs
- Single responsibility per job
- Pass IDs, not objects (serialization)
- Keep payloads minimal
Error Handling
- Use
retry_onfor transient failures - Use
discard_onfor permanent failures - Log errors with context
Quick Reference
| Pattern | Use When |
|---|---|
retry_on |
Transient errors (network, timeout) |
discard_on |
Permanent failures (record deleted) |
with_lock |
Preventing concurrent execution |
| Batch processing | Large datasets |
| Result tracking | Job status reporting |
Detailed Documentation
- patterns.md – Complete job patterns with examples
Basic Job Structure
class ProcessOrderJob < ApplicationJob
queue_as :default
retry_on ActiveRecord::RecordNotFound, wait: 5.seconds, attempts: 3
discard_on ActiveJob::DeserializationError
def perform(order_id)
order = Order.find(order_id)
OrderProcessor.new(order).process!
end
end
Queue Configuration
# config/sidekiq.yml
:queues:
- [critical, 6]
- [default, 3]
- [low, 1]
Testing Jobs
RSpec.describe ProcessOrderJob, type: :job do
include ActiveJob::TestHelper
it 'processes the order' do
order = create(:order)
expect {
ProcessOrderJob.perform_now(order.id)
}.to change { order.reload.status }.from('pending').to('processed')
end
it 'enqueues in the correct queue' do
expect {
ProcessOrderJob.perform_later(1)
}.to have_enqueued_job.on_queue('default')
end
end