tessl install github:ThibautBaissac/rails_ai_agents --skill solid-queue-setupgithub.com/ThibautBaissac/rails_ai_agents
Configures Solid Queue for background jobs in Rails 8. Use when setting up background processing, creating background jobs, configuring job queues, or migrating from Sidekiq to Solid Queue.
Review Score
90%
Validation Score
11/16
Implementation Score
92%
Activation Score
90%
Solid Queue is Rails 8's default Active Job backend:
# Add to Gemfile (included in Rails 8 by default)
bundle add solid_queue
# Install Solid Queue
bin/rails solid_queue:install
# Run migrations
bin/rails db:migrate# config/solid_queue.yml
default: &default
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 3
processes: 1
polling_interval: 0.1
development:
<<: *default
production:
<<: *default
workers:
- queues: [critical, default]
threads: 5
processes: 2
- queues: [low]
threads: 2
processes: 1# config/application.rb
config.active_job.queue_adapter = :solid_queue
# Or per environment
# config/environments/production.rb
config.active_job.queue_adapter = :solid_queueSolid Queue Setup:
- [ ] Add solid_queue gem
- [ ] Run solid_queue:install
- [ ] Run migrations
- [ ] Configure queues in solid_queue.yml
- [ ] Set queue adapter in config
- [ ] Create first job with spec
- [ ] Test job execution
- [ ] Configure recurring jobs (if needed)# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
def perform(user_id)
user = User.find(user_id)
UserMailer.welcome(user).deliver_now
end
end# app/jobs/process_payment_job.rb
class ProcessPaymentJob < ApplicationJob
queue_as :critical
# Retry on specific errors
retry_on PaymentGatewayError, wait: :polynomially_longer, attempts: 5
# Don't retry on these
discard_on ActiveRecord::RecordNotFound
# Custom error handling
rescue_from(StandardError) do |exception|
ErrorNotifier.notify(exception)
raise # Re-raise to trigger retry
end
def perform(order_id)
order = Order.find(order_id)
PaymentService.new.charge(order)
end
endclass UrgentNotificationJob < ApplicationJob
queue_as :critical
# Lower number = higher priority
# Default is 0
def priority
-10
end
def perform(notification_id)
# Process urgent notification
end
end# Enqueue immediately
SendWelcomeEmailJob.perform_later(user.id)
# Enqueue with delay
SendReminderJob.set(wait: 1.hour).perform_later(user.id)
# Enqueue at specific time
SendReportJob.set(wait_until: Date.tomorrow.noon).perform_later
# Enqueue on specific queue
ProcessJob.set(queue: :low).perform_later(data)
# Perform immediately (skips queue - use sparingly)
SendWelcomeEmailJob.perform_now(user.id)# config/recurring.yml
production:
daily_report:
class: GenerateDailyReportJob
schedule: every day at 6am
queue: low
cleanup:
class: CleanupOldRecordsJob
schedule: every sunday at 2am
sync:
class: SyncExternalDataJob
schedule: every 15 minutes# spec/jobs/send_welcome_email_job_spec.rb
require 'rails_helper'
RSpec.describe SendWelcomeEmailJob, type: :job do
let(:user) { create(:user) }
describe '#perform' do
it 'sends welcome email' do
expect {
described_class.perform_now(user.id)
}.to have_enqueued_mail(UserMailer, :welcome)
end
end
describe 'enqueueing' do
it 'enqueues the job' do
expect {
described_class.perform_later(user.id)
}.to have_enqueued_job(described_class)
.with(user.id)
.on_queue('default')
end
end
describe 'retry behavior' do
it 'retries on PaymentGatewayError' do
expect(described_class).to have_retry_on(PaymentGatewayError)
end
end
end# spec/rails_helper.rb
RSpec.configure do |config|
config.include ActiveJob::TestHelper
end
# In specs
it 'processes all jobs' do
perform_enqueued_jobs do
UserSignupService.call(user_params)
end
expect(user.reload.welcome_email_sent?).to be true
end
it 'enqueues multiple jobs' do
expect {
BatchProcessor.process(items)
}.to have_enqueued_job(ProcessItemJob).exactly(items.count).times
end# Development (runs in separate terminal)
bin/rails solid_queue:start
# Production (via Procfile)
# Procfile
web: bin/rails server
worker: bin/rails solid_queue:start# Gemfile
gem "mission_control-jobs"
# config/routes.rb
mount MissionControl::Jobs::Engine, at: "/jobs"# Check pending jobs
SolidQueue::Job.where(finished_at: nil).count
# Check failed jobs
SolidQueue::FailedExecution.count
# Retry failed job
SolidQueue::FailedExecution.last.retry
# Clear old completed jobs
SolidQueue::Job.where('finished_at < ?', 1.week.ago).delete_all| Sidekiq | Solid Queue |
|---|---|
perform_async(args) | perform_later(args) |
perform_in(5.minutes, args) | set(wait: 5.minutes).perform_later(args) |
sidekiq_options queue: 'critical' | queue_as :critical |
sidekiq_retry_in | retry_on with wait: |