Class to allow for preventing duplicate delayed jobs from being inserted into delayed jobs table
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib
.gitignore
README
Rakefile
TODO
VERSION

README

= unique_delayed_job

== Overview

You must have delayed_job installed as a gem or plugin to use this class.

Class for creating delayed jobs that can be de-duped with existing delayed jobs
already in the delayed jobs table. You just specify some additional columns on
your delayed_jobs table and set them to have uniqueness constraints. Then
specify these column values when you create a UniqueDelayedJob and if a
duplicate key is raised on insert, then the insert will just be ignored. There
are factory methods for creating a delayed job in the following ways:
* with a delayed job handler class (one that responds to perform())
* with an object, method and method arguments
* with a string to be evaled see the Delayed::Job.enqueue() method that accepts
  a block. (looks like the idea may have been added to delayed job here:
  http://github.com/dhh/delayed_job/commit/89c3a0b77470c0f8510d3c7a51a36cd07747d9a9)
  the block is yielded to, and the result (assumed to be a string) is stored as
  the code to be evaled when the job is deserialized.

== Configuration

You can add whatever columns you need to the delayed_jobs table, and put any
uniqueness constraints (or not) on them as you wish (unique columns, unique
composite keys etc.).

Note that by default, UniqueDelayedJob will modify any jobs that are currently locked
(locked_by is not null)...it will set all of the additional columns specified
on the job to NULL. (This allows for inserting a new job if a matching job is
already in process--and thus might be using out-of-date data.) If you do NOT
want this behavior, and do not want to insert a matching job if another job is
currently locked/being run, then make the following call. If you like, you can
change this before/after every job you insert if you want different jobs
to use different policies.

  UniqueDelayedJob.do_not_mark_locked_jobs_with_null()

== Examples

In each example below, the :user_id => 123 is just to illustrate that you can add
arbitrary additional column(s) to the delayed job row being inserted. Presumably,
the user_id column has uniqueness constraints on it...

(More than one column could be specified; uniqueness is enforced by the db schema,
and unique delayed job just catches and swallows any duplicate key exceptions.)

  # use a custom handler
  job = Delayed::UniqueDelayedJob.use_handler(MyHandlerClass.new( ...), :user_id => 123)
  job.enqueue  # use default priority and run_at

  # use a method call (similar to using send_later on the object)
  record = MyActiveRecord.find(1)
  job = Delayed::UniqueDelayedJob.call_method(record,
                                              :a_method,
                                              [arg1, arg2],
                                              :user_id => 123)
  job.enqueue(1) # use priority of 1

  # specify a block of code to execute with string (inside a block)
  # note that the block could be complex logic that results in a string that is
  # arbitrary ruby code to be evaled
  # see Delayed::Job::enqueue(args, &block)
  job = Delayed::UniqueDelayedJob.run_eval(:user_id => 123) do
    'SomeClass.perform_some_slow_action'
  end
  job.enqueue(2, 1.hour.from_now) # run with priority 2 and run at 1 hour from now