You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ruby新手求助:Delayed Job未按延迟时间执行问题

Hey there! Let's troubleshoot why your Delayed Job isn't waiting the 1 minute you specified before firing off that auto-message. I’ve dealt with this exact issue a few times, so let’s walk through the most common fixes:

1. You’re calling the Job the wrong way (the #1 culprit!)

Most new folks accidentally trigger the job immediately instead of queuing it with a delay. If you’re doing something like:

# ❌ This runs RIGHT NOW, no delay
MailingJob.new.perform(your_args)
# Or this, which also skips delay
MailingJob.perform_now(your_args)

That’s why it’s executing instantly. Instead, use the proper delayed syntax:

Option 1 (Rails Active Job + Delayed Job):

This is the cleanest approach for modern Rails apps:

# ✅ Delays 1 minute before running
MailingJob.set(wait: 1.minute).perform_later(your_args_here)

Option 2 (Classic Delayed Job syntax):

If you’re using the older direct Delayed Job integration:

# ✅ Also delays 1 minute
MailingJob.delay(run_at: 1.minute.from_now).perform(your_args_here)

2. Check your Job class inheritance

Make sure your MailingJob is set up to work with Delayed Job properly. For Rails 5+, it should inherit from ApplicationJob (which is pre-configured to work with Delayed Job if you’ve set it as your adapter):

# app/jobs/mailing_job.rb
class MailingJob < ApplicationJob
  queue_as :default # Optional, but good practice for queue management

  def perform(*args)
    # Your auto-message logic goes here
    puts "Sending auto-message after delay!"
  end
end

If you’re on an older Rails version, ensure your class includes Delayed::Job or uses the handle_asynchronously method (but the Active Job approach is way better if you can use it).

3. Watch out for duplicate methods in your controller

You mentioned you created the same perform method in your controller—this could be causing confusion! If you’re calling perform directly in your controller without referencing the MailingJob class, you’re just running the controller’s method immediately, not the delayed job.

Double-check your controller code to make sure you’re explicitly calling the Job class, like this:

# In your messages controller
def create
  @message = current_user.messages.create(message_params)
  # Make sure you're calling the JOB, not a controller method
  MailingJob.set(wait: 1.minute).perform_later(@message.id)
  redirect_to messages_path, notice: "Message sent!"
end

4. Verify your Delayed Job worker is running

Wait, you said the code "executes normally"—but just to be safe: make sure the Delayed Job background worker is actually running. If it’s not, jobs will sit in the database until you start it. Run this in your terminal:

# Start the worker (production/development)
bundle exec delayed_job start

# Or for development, you can run it in the foreground to see logs
bundle exec rake jobs:work

Quick Test to Confirm

Hop into your Rails console and run this to verify the delay is being set correctly:

# Queue a job with a 1-minute delay
job = MailingJob.set(wait: 1.minute).perform_later
# Check when it's scheduled to run
puts job.scheduled_at # Should show a time 1 minute from now

If scheduled_at shows the correct future time, then the issue was likely that you were calling the job incorrectly before. If it still shows the current time, double-check that you’re not overriding the delay somewhere in your Job class or controller.


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

火山引擎 最新活动