I have been using Delayed Job quite a lot at my current job at FFX. And I have encountered some interesting and hard to debug issues with it.
I am outlining some of few best practices that hopefully makes your life with DJ easier:
Read Delayed Job common problems
Go on, go there first - I’ll wait :): Delayed Job common problems
Run Delayed Job worker on your dev environment
If you don’t run Delayed Job worker on your dev environment, you are bound to find surprises when you deploy your code to staging or production - trust me :)
At work, we used to have this our delayed job initializer:
Delayed::Worker.delay_jobs = !(Rails.env.development? || Rails.env.test?)%
This means that on development and test environment, jobs are executed immediately by the same server that schedules the job, in other words, NOT delayed.
While it is a sensible setting for test environment, it is not probably not a good idea for dev.
Why?
Because by doing this, you are not adhering to maintaining Dev/prod parity. Where there is a parity gap between environments, bad and unexpected things tend to happen.
Set destroy_failed_jobs to false
If you ever encountered an issue where you think your job has been run successfully but you just can’t see the effect of the job.
For example, you have a delayed job that sends out email - the email never gets sent, but the job is not reported as error.
Even more confusing you check on your delayed_jobs
table - the job is not there.
Well, in this case I’d want to suggest that the DJ failed even before running your job.
DJ has this behavior in that when it fails to parse the YAML code in the handler, it will just remove the job from delayed_jobs
table.
This is the only time when I ever encountered this behavior.
You can do the following to prevent the removal of the job (this is from the common problems link above):
Delayed::Worker.destroy_failed_jobs = false
Honestly, I think this config should default to true, but anyway.
Pass simple values as parameters to the job
Related to the issue above, the failure to parse YAML can sometime be caused by the parameters that you send to your job.
It is best to keep your job to accept simple values as parameters.
For example, you have a job that sends email to a user and your job might be like this:
class MarketingMailer
def initialize(member)
@member = member
end
def perform
...
end
end
I would suggest that instead of initializing the job with member object, pass in a member identifier instead (e.g member_id)
For example:
class MarketingMailer
def initialize(member_id)
@member = Member.find(member_id)
end
def perform
...
end
end
Conclusion
That is all I got - happy hacking!