You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中Delayed Job执行两次问题排查与修复求助

Hey there! Let's break down why your SimpleJob is running twice and how to fix it. Based on your setup, here are the most likely causes and solutions:

Why Your Job Runs Twice & How to Fix It

1. Initializer Script Gets Loaded Multiple Times

You mentioned adding SimpleJob.schedule! in config/initializers/job_initializers.rb. Rails can re-run initializers in certain scenarios—like code reloading in development mode, or when using a server that spins up multiple worker processes (Puma/Unicorn). Each reload/process launch triggers the initializer again, scheduling the job twice.

Fix:
Add a guard clause to ensure the job is only scheduled once:

# config/initializers/job_initializers.rb
# Option 1: Check if the job already exists in Delayed Job
unless Delayed::Job.exists?(handler: /SimpleJob/)
  SimpleJob.schedule!
end

# Option 2: Use a global flag to prevent repeats
unless defined?($simple_job_already_scheduled)
  $simple_job_already_scheduled = true
  SimpleJob.schedule!
end

2. Multiple Server Workers Trigger Scheduling

If your app server runs multiple worker processes (common in production or even development with Puma's default settings), each process will execute the initializer independently—resulting in duplicate job schedules.

Fix:
Move the scheduling logic out of initializers and into a one-time rake task. Create lib/tasks/schedule_jobs.rake:

namespace :jobs do
  desc "Schedule one-time recurring jobs"
  task schedule: :environment do
    SimpleJob.schedule!
  end
end

Run it manually after starting your server: rails jobs:schedule, or add it to your deployment script (like Capistrano) to run once per deploy.

3. Delayed Job's Retry Mechanism Is Triggering

If your job hits a temporary error (e.g., a brief database connection blip) during execution, Delayed Job defaults to retrying the task. If the error resolves quickly, you'll see two execution logs and two database records.

Fix:
Check your logs for retry messages, then adjust the job's retry policy:

class SimpleJob < ApplicationJob
  queue_as :default
  # Disable retries entirely if you don't need them
  retry_on StandardError, attempts: 0
  # Or set longer wait times to avoid immediate repeats
  # retry_on StandardError, wait: 5.minutes, attempts: 3

  def perform
    # Your job logic here
  end
end

4. Flawed Scheduling Logic in schedule!

If your SimpleJob.schedule! method doesn't check for existing pending jobs, every call will create a new task—leading to duplicates.

Fix:
Update the schedule! method to only create a job if none are pending:

class SimpleJob < ApplicationJob
  def self.schedule!
    # Skip if there's already a pending SimpleJob
    unless Delayed::Job.where(handler: /SimpleJob/).exists?
      set(wait: 1.minute).perform_later # Adjust wait time as needed
    end
  end
end

5. Development Mode Code Reloading

In development, Rails auto-reloads classes when you modify code, which can re-run initializers and re-schedule the job.

Fix:
Avoid scheduling jobs via initializers in development. Instead, run SimpleJob.schedule! manually in the Rails console when you need it, or use the rake task mentioned earlier.


内容的提问来源于stack exchange,提问作者onder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 06:17:32