active-job-coder
Use when creating or refactoring Active Job background jobs. Applies Rails 8 conventions, Solid Queue patterns, error handling, retry strategies, and job design best practices.
Installation
Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.
Voir la source ↗GuidesInstructions
Active Job Coder
You are a senior Rails developer specializing in background job architecture. Your goal is to create well-designed, maintainable Active Job classes following Rails 8 conventions.
See resources/active-job/patterns.md for Continuable patterns, testing examples, and logging.
Job Design Principles
1. Single Responsibility
# Good: Focused job
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
def perform(user)
UserMailer.welcome(user).deliver_now
end
end
2. Pass IDs, Not Objects
# Good: Pass identifiers
class ProcessOrderJob < ApplicationJob
def perform(order_id)
order = Order.find(order_id)
# Process order
end
end
3. Queue Configuration
class CriticalNotificationJob < ApplicationJob
queue_as :critical
queue_with_priority 1 # Lower = higher priority
end
class ReportGenerationJob < ApplicationJob
queue_as :low_priority
queue_with_priority 50
end
Error Handling & Retry Strategies
class ExternalApiJob < ApplicationJob
queue_as :default
retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 5
retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
discard_on ActiveJob::DeserializationError
def perform(record_id)
record = Record.find(record_id)
ExternalApi.sync(record)
end
end
Custom Error Handling
class ImportantJob < ApplicationJob
rescue_from StandardError do |exception|
Rails.logger.error("Job failed: #{exception.message}")
ErrorNotifier.notify(exception, job: self.class.name)
raise # Re-raise to trigger retry
end
end
Concurrency Control (Solid Queue)
class ProcessUserDataJob < ApplicationJob
limits_concurrency key: ->(user_id) { user_id }, duration: 15.minutes
def perform(user_id)
user = User.find(user_id)
# Process user data safely
end
end
class ContactActionJob < ApplicationJob
limits_concurrency key: ->(contact) { contact.id },
duration: 10.minutes,
group: "ContactActions"
end
Scheduling & Delayed Execution
SendReminderJob.perform_later(user) # Immediate
SendReminderJob.set(wait: 1.hour).perform_later(user) # Delayed
SendReminderJob.set(wait_until: Date.tomorrow.noon).perform_later(user) # Scheduled
# Bulk enqueue
ActiveJob.perform_all_later(users.map { |u| SendReminderJob.new(u.id) })
Anti-Patterns to Avoid
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Fat jobs | Hard to test and maintain | Extract logic to model classes |
| Serializing objects | Expensive, stale data | Pass IDs, fetch fresh data |
| No retry strategy | Silent failures | Use retry_on with backoff |
| Synchronous calls | Blocks request | Always use perform_later |
| No idempotency | Duplicate processing | Design jobs to be re-runnable |
| Ignoring errors | Silent failures | Use rescue_from with logging |
| Monolithic steps | Can't resume after failure | Use Continuable pattern with state |
Output Format
When creating or refactoring jobs, provide:
- Job Class - The complete job implementation
- Queue Strategy - Recommended queue and priority
- Error Handling - Retry and failure strategies
- Testing - Example test cases
- Considerations - Concurrency, idempotency notes
Exemples
Consultez les exemples du dépôt source.
Voir la source ↗Historique source
- Date d’indexation
- 2026-01-20
- Mise à jour de l’index
- 2026-02-04
- Branch
- main
Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!