DeferredJob is a small library meant to work with Resque or Sidekiq that allows you to add a set of pre-conditions that must be met before a job kicks off.
$ gem install deferred_job
You'll need to tell DeferredJob which message processing system you're using:
DeferredJob::Job.adapter = :sidekiq
To create a deferred job, you must give it an id, and the name/arguments of a worker to kick off when the preconditions are met:
job = DeferredJob::Job.create(id, SomeWorker, 'worker', 'args')
NOTE: If you try to re-create an existing job, you'll clear it out.
To add preconditions, you can use #wait_for
. So if you wanted to wait until
a few things are done, you can add them one at a time, or in bulk:
job.wait_for('import-1-data')
job.wait_for('import-2-data')
job.wait_for('import-1-photos', 'import-2-photos')
At any time before a job executes, you can check out its preconditions with a few inspection methods:
# See if we are waiting for a specific thing
job.waiting_for?('import-1-data') # true
# See what things we are waiting for
job.waiting_for # 'import-1-data', 'import-2-data', ...
# Count the number of things we're waiting for
job.count # 4
# See if we're waiting on anything at all
job.empty? # false
As you finish the preconditions, the same way you added them with #wait_for
,
you remove them with #done
. When the set is empty, the job will kick
off with the args you specified in the initializer. You don't need
to finish things in the same order you put them in (and hopefully you
aren't):
job.done('import-1-data')
job.done('import-1-photos', 'import-2-photos')
job.done('import-2-data') # job kick off!
Most times, you'll have the need to use a DeferredJob
in multiple
pieces of your code that don't see each other (ie: inside of your workers).
In that case, load a previous job like so:
# Check existence if you'd like
DeferredJob::Job.exists? id # true
# Load the job up
job = DeferredJob::Job.find id
NOTE: If you try to find a job that does not exist, you'll raise an
exception (DeferredJob::NoSuchJob
).
By default, DeferredJob
will use the same redis instance as your message processing tool.
If you'd like to change that, you can set the redis instace like so:
DeferredJob::Job.redis = your_instance
By default, DeferredJob
will generate redis keys that look
like deferred-job:#{id}
. It can be useful to change that, so you can
specify a new lambda expression for generating the keys:
DeferredJob.key_lambda = lambda { |id| "job:#{id}" }
Distributed under the MIT License. See the attached LICENSE file.