I've been trying to figure out how to send delayed mail using delayed_job with rails 3. I've tried pretty much every combination of feasible possibilities I can think of - I can get the mail to run in the background, I just can't get it to delay the sending to a future time. The delayed_jobs table in the db clears the tasks, the log says 'sent', the delayed_job task processor picks up the task & says sent without failure...but the mail is either:
if I try to send in the future.
If anyone could offer a bare-bones example of a rails 3 delayed_job that sends mail in the future, I'd be really appreciative. I'm sure lotsa folks do this so I suspect I'm missing something obvious. One (of countless) combinations I've tried below:
delayed_job: 2.1.2 rails: 3.0.3 actionmailer: 3.0.3
Controller:
class TestmailerController < ApplicationController
def index
Testmailer.delay.test_mail
end
end
Mailer:
class Testmailer < ActionMailer::Base
def test_mail
mail(:to => '([email protected]', :from => '(removedforprivacy)@gmail.com', :subject => 'Testing Delayed Job', :content_type => 'text/plain').deliver
end
handle_asynchronously :test_mail, :run_at => Proc.new { 2.minutes.from_now }
end
relevant mail part of config/environments/development.rb:
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "(removedforprivacy)",
:password => "(removedforprivacy)",
:authentication => "plain",
:enable_starttls_auto => true
}
Job command:
rake jobs:work
Delayed Job, also known as DJ, makes it easy to add background tasks to your Rails applications on Heroku. You can also use Resque and many other popular background queueing libraries. Delayed Job uses your database as a queue to process background jobs.
Restart Delayed Job on deploy You must remove that one now if you have it. It basically does the same thing that we will add now but without using upstart. We will now create a new file that will host our start, stop and restart tasks. Create a file at lib/capistrano/tasks/delayed_job.
The most simple way to check whether delayed_job is running or not, is to check at locked_by field. This field will contain the worker or process locking/processing the job. Running Delayed::Job. where('locked_by is not null') will give you some results, if there are jobs running.
I agree with andrea - I was having this exact problem, and after switching my local development database from sqlite to mysql, I can run code like
Emailer.delay({:run_at => 5.minutes.from_now}).welcome(@user)
and it sends the email 5 minutes later. Note that you might need a bigger delay than five minutes (in case of time zone weirdness) to be sure it is working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With