ActiveJob In Retrospect
Recently, I replaced
Resque (why it’s resque and not sidekiq is a whole other matter), which got me into thinking of ActiveJob usefulness as a whole.
Lots of methods
Quite a different implementation
Hard to remember
Hard to switch to projects, where a database is not the one you’re used to.
And of course, it gives an ability to switch databases without changing code (unless you use db specific features as most of us do)
Now let’s look at ActiveJob’s adapters.
class SidekiqAdapter def enqueue(job) #:nodoc: job.provider_job_id = Sidekiq::Client.push( "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] ) end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push( "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ],"at" => timestamp ) end end
class ResqueAdapter def enqueue(job) #:nodoc: JobWrapper.instance_variable_set(:@queue, job.queue_name) Resque.enqueue_to job.queue_name, JobWrapper, job.serialize end def enqueue_at(job, timestamp) #:nodoc: unless Resque.respond_to?(:enqueue_at_with_queue) raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \ "resque-scheduler gem. Please add it to your Gemfile and run bundle install" end Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize
And that’s it, just two methods. Do we really need an abstraction layer for just two methods?
Sometimes yes, but do we really need an abstraction layer that prevents us from using features without monkey patching (not to say it’s an absolute evil, but it rather error prone) or adds unnecessary performance overhead?
Rails is very good at tools that, provided out of the box, just work. Minimum if any configuration and you all set. However, setting up any background job framework is simple. Just five lines of code for sidekiq and a little more for resque.
Another feature that
ActiveJob provides is an ability to change background processing backend with one line of code. Although, I think it’s a rare use case. I used it once to switch from resque to sidekiq to resque again. And it wasn’t one line of code. With
ActiveJob the only thing I avoided is a few global ‘Find And Replace’ over the codebase.
When something is a default and works out of the box, there is a lot of inner resistance in replacing it.
ActiveJob brings little agility, gives another default interface to learn how to work with and how to test properly. It also adds the possibility that some external gems won’t work and you would have to somehow monkey patch this gem to make it work or get rid of
ActiveJob altogether. All this and not much profit in return.