In my Rails app (4.2.4), I have been trying to get asynchronous mail sending to work.
I installed delayed_job as my queue adapter, and set it as the adapter in several places: config/application.rb, config/environments/{development,production}.rb, and config/initializers/active_job.rb.
Installation:
I added this to my Gemfile:
gem 'delayed_job_active_record'
Then, I ran the following commands:
$ bundle install
$ rails generate delayed_job:active_record
$ rake db:migrate
$ bin/delayed_job start
In config/application.rb, config/environments/production.rb, config/environments/development.rb:
config.active_job.queue_adapter = :delayed_job
In config/initializers/active_job.rb (added when the above did not work):
ActiveJob::Base.queue_adapter = :delayed_job
I've also run an ActiveRecord migration for delayed_job, and started bin/delayed_job before running my server.
That being said, any time I try:
UserMailer.welcome_email(#user).deliver_later(wait: 1.minutes)
I get the following error:
NotImplementedError (Use a queueing backend to enqueue jobs in the
future. Read more at http://guides.rubyonrails.org/active_job_basics.html):
app/controllers/user_controller.rb:25:in `create'
config.ru:25:in `call'
I was under the impression that delayed_job is a queueing backend... am I missing something?
EDIT:
I can't get sucker_punch to work either. When installing sucker_punch in the bundler, and using:
config.active_job.queue_adapter = :sucker_punch
in config/application.rb, I get the same error and stack trace.
If you are having this issue in your development environment even though you are using an adapter capable of asynchronous jobs like Sidekiq, make sure that Rails.application.config.active_job.queue_adapter is set to :async instead of :inline.
# config/environments/development.rb
Rails.application.config.active_job.queue_adapter = :async
Provide you are following all the steps listed here, I feel you didn't start delayed_job running
bin/delayed_job start
Please also check you run
rails generate delayed_job:active_record
rake db:migrate
Try this:
in controller:
#user.delay.welcome_email
in your model
def welcome_email
UserMailer.welcome_email(self).deliver_later(wait: 1.minutes)
end
Figured out what it was: I typically start my server and everything associated with it using a single shell script. In this script, I was running bin/delayed_job start in the background, and starting the server before bin/delayed_job start finished. The solution was to make sure delayed_job start finished before starting the server by running it in the foreground in my startup script.
Thanks everyone for all the help!
Related
I'm trying to execute a simple rake task using whenever gem but the code isn't being executed.
I already set the environment to development, I updated the cron using the whenever --update-crontab command and the rake task works well if I run the command on console. But, when I run the server the log file is not being generated.
I saw a question here too with the same problem but it was solved setting the environment to development, but didn't work out for me.
My rake task:
namespace :testando do
task :consulta => :environment do
produto = Produto.first
puts produto.nm_produto
end
end
My schedule.rb:
set :output, "#{path}/log/cron_log.log"
set :environment, 'development'
every 1.minute do
rake "testando:consulta"
end
I'm using rails 5.0.0.1 and I'm programing in Cloud9, so I think the OS is Ubuntu.
What's missing ?
Update:
I followed the instructions of the main answer in this topic Cron job not working in Whenever gem
And it worked! The task is running even with the server not being started (with "rails s" command).
please run crontab -l to see if you have updated the crontab successfully
I have a Rails 3.x application with Resque. I run the resque command with:
nohup rake RAILS_ENV=production environment resque:work QUEUE='*' & >>/tmp/resque.log 2>> /tmp/resque.err.log
Every other day the process dies, but the two output files are always empty. Any other way of figuring out why the Resque process goes down?
Try the super awesome Pry console. This is similar to irb only much more advanced.
You can use binding.pry inside your perform method or preferably in a hook which will start up a pry console using which you can debug. Helped me in similar situations a lot.
Here's what my Procfile looks like:
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
worker: bundle exec rake jobs:work
I intend to add a worker process because I wish to run some background jobs. I'm following these instructions
This is what I noticed:
No problems encountered if the worker is started separately.
When I keep the second line in the Procfile and don't not change anything else, the rails server serves a couple of requests and hangs after that
As mentioned here , I've added STDOUT.sync = true to config/environments/development.rb and verified the same in the rails console. Did not work.
Tailed log/development.log and compared it against the stuff that foreman outputted to the shell and noticed that both matched for a couple of requests and then foreman stopped printing out stuff to the shell - the next request would then hang
I updated foreman using foreman.pkg as mentioned here and verified the same with [6]
It was mentioned here that this might be caused due to a stray debug statement. I'm not using the debugger and I do not have the pry gem or the ruby-debug gem in my Gemfile.lock
I believe the symptoms are similar to this related unanswered question
Please help!
[6]:
which foreman
/usr/bin/foreman
ls -lah /usr/bin/foreman # checked the updated date
Tracked and resolved here:
https://github.com/ddollar/foreman/issues/244
TL;DR: Install the gem, don't use foreman.pkg
I'll add than if you're using Heroku, the foreman version included with the heroku toolbelt has the same issue.
Use the one you can get with gem install foreman instead.
I've added gem 'delayed_job' to my gem file and ran a bundle install.
After that I ran rails generate delayed_job
I've created a controller named Online with a method online.
In turn after the method declaration I added the following line:
handle_asynchronously :online
I start up my app, but the code in that method does not run.
What am I doing wrong?
I'd guess that you haven't done rake jobs:work anywhere. From the fine manual:
Running the jobs
You can invoke rake jobs:work which will start working off jobs. You can cancel the rake task with CTRL-C.
You might want to set up Foreman to start the Rails server and the Rake task at the same time in your development environment; there's even a Railscast about it:
http://railscasts.com/episodes/281-foreman
I have no problems with running it in development mode via rake jobs:work. However, I'm somehow unable to figure out how to use it in production. I'm using Capistrano for deployment.
Thanks for any advice!
If you install delayed_job as a gem you need to run the generator in order to create the script scripts/delayed_job and set run permissions.
Then you can follow the instructions on How to configure Capistrano for Delayed Job to hook it up in your Capistrano file.
See this answer. In a nutshell, use the Collective Idea fork of delayed_job. It contains a script called delayed_job that can be used.
You can run the generated delayed_job script as follows:
RAILS_ENV=production script/delayed_job start
Hope this helps
My first thought will be to add a after deploy task in capistrano to run the rake jobs:work task. you might need to check if the process is already running and restart it.
If you are running it via rake then couldn't you just run however often you wanted via cron? The whenever gem is a great interface to this from ruby.