Setting up Delayed Job with Rails 4.2!
Delayed Job Jobs
When I first setup delayed job I tried to follow the Delayed Job documentation but also heavily relied on the book ‘The Rails 4 Way’, which is an awesome Rails book.
However, when I started to do some more testing on my jobs I started noticing a few things that didn’t feel quite right.
Here’s a break down of what I started with for some custom jobs.
Then in my controller I had something like this.
Testing this in isolation in the tests/jobs/foo_job_test.rb
was easy enough and worked as expected following the Rails Testing Guides.
But then I tried to test this where it was being enqueued, in the controller, and that’s when I felt like I must have done something wrong.
I think I was essentially bypassing ActiveJob and enqueuing the job directly with Delayed Job. If I’m right, that means you don’t have to set config.active_job.queue_adapter = :delayed_job
in your config/application.rb
file if you do it this way because you’re not using ActiveJob and it’s adapter. This makes the Delayed Job section of ‘The Rails 4 Way’ make a lot more sense to me. This also makes the Delayed Job ReadMe make more sense to me. For Rails 4.2 it basically says to set the adapter then see the rails guides. Even as I’m writing this, I’m kind of laughing at myself for not clueing in earlier.
I could verify through the console that the job was enqueued to my backend and executing them through Delayed Job as expected but automating the testing was a bit harder to verify the jobs were being enqueued.
My original test setup for my controller was like this.
Once I tried to make sure the job was enqueued or performed with ActiveJob’s custom assertions my tests would fail.
This felt weird to me. I didn’t like how in my code I was using Delayed::Job to enqueue the job and Delayed::Worker to force immediate execution of the job. The job was executed, and the post.updated_by
was updated but I wanted to make sure the job was being enqueued here not performed. And I wanted to do this with ActiveJob
s api instead and let it’s adapters handle translating to the backend. What if I decided to change to Sidekiq in a few weeks, I’d have to update this code.
After playing around and reading some docs I was able to update the code to be a little more backend agnostic.
This now works as I had expected it to from the beginning following the Rails Guides a bit more.
The Job test makes sure the job executes properly. The controller test doesn’t need to do that then. It just needs to make sure my queuing backend receives the job and queues it. This is also backend independent, using ActiveJob’s api and adapters to handle telling my queuing framework of choice what to do.
Last note, go with your gut. It may not be right, but if you go with it and dig into the problem you’ll at least understand why you were questioning things.