#171 Delayed Job (revised)
Jan 07, 2012 | 8 minutes | Plugins, Background Jobs
Long requests should be moved into a background process, and Delayed Job is one of the easiest ways to do this because it works with an Active Record database.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Lower priority numbers have higher priority. It is in documentation
Anyway great tutorial ! Thanks
+1
+1 I believe it is supposed to be based on the LINUX nice values
You must've been lucky with using delay as a Class method. I wonder what your stack is (ruby version/gem version/bundler version/rails version).
Gives a NoMethodError on Class when executing the job. The target class doesnt serialize/deserialize properly it seems. Seems like there are 3 open tickets relating to this on Github.
Same problems for me
Obligatory "Me too". There was a note I saw about problems with the thin web server. Switched to plain old webrick to no avail. (Of course...) Works fine in dev. Only fails in production.
Seems like this problem is specific to ruby1.8
try this in your irb session
If you dont get your AR model back, there is a problem. I'm getting Class returned on ruby 1.8.7 and the correct result on ruby 1.9.3-p0
Just FYI
Dev works fine, production is the problem.
I get no such file to load -- rubygems
I suspect the delayed_job file. Should I change the delayed_job script file in any way? my production is bundled with rails 3.0.11 and ruby 1.8.7p352.
I tried which ruby and then changed the first line of the delayed_job, but then I get permission problem. I also tried chmod 755 on the which ruby path. any ideas?
I can not change to 1.9.2 ruby, because of some older apps there.
While I like how the #delay method looks in the code, automatically serializing/deserializing objects, it does feel somewhat dirty. I recall it being fairly slow when working with large objects, and in most cases I think providing a hash of options along with the model's id would be faster. But, please do correct me if I'm wrong about that. I think that the less data you store in the database, faster the retrieval and serialization/deserialization will be when just using Struct classes, but it does mean you need to write a bit more code for everything you want to queue up. And, if you're going to do that then you might want to consider using Resque instead. I've used both a few times, and they both have their pros and cons. Note: I haven't tried out the new Delayed Job 3 that was recently released.
Can i configure different delay time between jobs calls for different queues?
Hi Ryan,
i see that there are some hooks you can define using delayed job.
i want to do some task after the job is done and, as the docs suggest i add the method
in my class but it never been called.
What is the right way to use the hooks or maybe there is some other way to define callbacks instead?
Did you ever figure out how to use the hooks? I'm trying to figure it out, too.
It appears you need to use a "Custom Job", but I am unable to get the custom job to execute. I see the call to enqueue, I see the record inserted into delayed_jobs table. Then I see the job being locked, and the job being deleted from the table. No other hooks are called, nor is my process.
I know that sending the actual emails/newsletters is not the focus of this episode, but I would like to see how Ryan would setup sending newsletters like this. I haven't been able to find a good example of sending group emails in Rails.
Hi Ryan. Instead of using daemons gem when running 'sciprt/jobs'. Could you just use foreman and have it 'run bundle exec rake jobs:work'?
I use foreman in development and in production too so this would be useful to know.
DelayedJob doesn't seem to work with JRuby unfortunately, at least not on windows -- as best I can tell. It will queue jobs, but starting a background job fails.
The jruby-rack-worker gem comes to the rescue: http://github.com/kares/jruby-rack-worker. It lets you still use delayed_job to schedule jobs, but provides a different way to kickoff worker processes that is more friendly to JRuby and also works on a windows tomcat server. I'm not advocating deploying on windows, but if you're forced to do that for some reason and you also need to use JRuby -- take a look at jruby-rack-worker.
I'm using delayed_job (Rails 3.1) on Heroku. It seems to stall a lot, and can be tricky to start workers. I'm constantly paranoid that delayed_job may have fallen asleep and jobs are piling up in the queue (this happens pretty often, actually). Anyone know of any good resources for getting delayed_job to work reliably on Heroku? I installed the 'daemons' gem, but I generally just run "heroku rake jobs: work" to get things going again.
I'm sure I'm just doing it wrong, but I can't find too much out there to help me get everything set up to run efficiently.
Suggestions?
Hey did you ever find a solution to the heroku problems you were having? Have you seen this article on heroku? I was just about to implement delayed_job on heroku when I saw your post.
https://devcenter.heroku.com/articles/delayed-job
Changed from Bj(no longer supported in Rail3) to Delayed_job but seems not to handle rails runner.
lib/report_job.rb
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
bundle exec rails runner "#{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
end
Error in last_error field.
{undefined method `runner' for #ReportJob:0xc28f080
OUCH! .... will try Resque.
One very good explanation why my approach does not work.
http://stackoverflow.com/questions/10930300/delayed-job-and-prawn-scripts
load "#{Rails.root}/jobs/#{prawn_script_name}.rb" DOES WORK.
BUT
I need to pass arguments e.g account_id to the Prawn scripts to scope the data for the pdfs.
runner allows ARG[]s to be passed but "load" does not!
Delayed_job has the arguments in its table but how do I make these accessible to the Prawn scripts?
This is my next hurdle to overcome.
Hi Ryan,
Awesome info. Two questions:
Wouldn't it be better to call the delay method from within the Newsletter model (or use handle_asynchronously)? That way the background functionality can be encapsulated into the Newsletter model and away from the controller. Better if we need to change it later...?
It seems to me that the big difference between serializing the object and just saving the ID is the state of the object. If you serialize it, then you are capturing the state when the delay method is called. If you just save the ID, then it will use the state of the object when the Newsletter is delivered.
I imagine that one or the other would be desirable, depending on the details of the application.
For me it seems to make no difference if ID or object is serialised: in both cases the state captured is the one when the delivery happens, not the state when delay is called... ??
Using delayed_job gem with my rails 3 app on development working great but when I tried to use it on production using capistrano it gives me these error
script/delayed_job: Permission denied
I am using their method and I followed your method
https://github.com/collectiveidea/delayed_job/wiki/Rails-3-and-Capistrano
The reason why is explained here https://github.com/collectiveidea/delayed_job/issues/659.
Hy all, i have installed delayed_job gem,
I have an rails app qith mongoid, and the gem save correctly the queue in mongodb (db.delayed_backend_mongoid_jobs), but not exectue the queue command, why?
Hi all,
What might have been obvious to some but was not to me was the necessity to pay on Heroku a worker (35$) to have the queue taken care of if I'm not mistaken.
https://devcenter.heroku.com/articles/delayed-job
Best
Nicolas
You are correct, Heroku requires a separate worker dyno to launch background jobs.
You can use the Workless gem, which creates and kills a worker when DelayedJob is called. Heroku will only bill you the uptime ($0.05/h), not the full $35/m.