Class: Delayed::UniqueDelayedJob
- Inherits:
-
Object
- Object
- Delayed::UniqueDelayedJob
- Defined in:
- lib/delayed/unique_delayed_job.rb
Overview
allows for specifying additional columns on the delayed_jobs table to help prevent duplicate delayed jobs from being entered into the queue…but still keep an easy interface to enqueuing delayed jobs
Constant Summary collapse
- @@mark_all_locked_jobs_with_null =
true
Instance Attribute Summary collapse
-
#columns ⇒ Object
Returns the value of attribute columns.
Class Method Summary collapse
-
.call_method(object, method, args_arr, columns = {}) ⇒ Object
factory method to create a new UniqueDelayedJob by specifying a method ton call.
-
.do_not_mark_locked_jobs_with_null ⇒ Object
override the default behavior, and DO NOT mark the columns on a delayed job that is currently locked to null.
-
.mark_all_locked_jobs_with_null ⇒ Object
enable the polciy that all delayed job rows that are marked with non-null locked_by should have their columns set to null…ensuring that if a job is currently executing then we CAN insert another delayed job with the same unique keys.
-
.run_eval(columns = {}, &block) ⇒ Object
factory method to create a UniqueDelayedJob by specifying a block that is executed and whose result is stored as a string to be evaled by delayed_job arguments: - columns: hash of column names and values to insert into the delayed jobs table in addition to the handler NOTE: a block is expected —————————————————————————.
-
.use_handler(handler, columns = {}) ⇒ Object
factory method to create a new UniqueDelayedJob from a delayed job handler object (see delayed job documentation for requirements).
Instance Method Summary collapse
-
#add_delayed_jobs_columns(new_columns) ⇒ Object
specify some additional columns to set in the delayed jobs table for this row.
-
#enqueue(priority = nil, run_at = nil) ⇒ Object
put the job on the delayed jobs queue.
Instance Attribute Details
#columns ⇒ Object
Returns the value of attribute columns.
142 143 144 |
# File 'lib/delayed/unique_delayed_job.rb', line 142 def columns @columns end |
Class Method Details
.call_method(object, method, args_arr, columns = {}) ⇒ Object
factory method to create a new UniqueDelayedJob by specifying a method ton call. will use delayed jobs’ PerformableMethod class to enqueue the job
arguments:
- object: the object (or class or module) on which to call the method
- method: the method to call (specify a symbol or string)
- args_arr: an array of arguments to pass in the method call)
- columns: hash of column names and values to insert into the delayed
jobs table in addition to the handler
62 63 64 65 |
# File 'lib/delayed/unique_delayed_job.rb', line 62 def self.call_method(object, method, args_arr, columns = {}) job = self.new(Delayed::PerformableMethod.new(object, method, args_arr), columns) end |
.do_not_mark_locked_jobs_with_null ⇒ Object
override the default behavior, and DO NOT mark the columns on a delayed job that is currently locked to null. this prevents inserting a duplicate job with a job that is currently running (e.g. if you only want to run the job once). Default is mark_all_locked_jobs_with_null (see that method)
34 35 36 |
# File 'lib/delayed/unique_delayed_job.rb', line 34 def self.do_not_mark_locked_jobs_with_null @mark_all_locked_jobs_with_null = false end |
.mark_all_locked_jobs_with_null ⇒ Object
enable the polciy that all delayed job rows that are marked with non-null locked_by should have their columns set to null…ensuring that if a job is currently executing then we CAN insert another delayed job with the same unique keys. This is useful if you want to run a job every time some event occurs, but you’re using this gem just to prevent having the same job twice in the queue. But if a job is currently running, it may miss the change in state due to the latest event, so a new job does need to be added to the queue. setting the columns to null on any jobs currently locked should ensure this behavior. This is the default behavior.
25 26 27 |
# File 'lib/delayed/unique_delayed_job.rb', line 25 def self.mark_all_locked_jobs_with_null @mark_all_locked_jobs_with_null = true end |
.run_eval(columns = {}, &block) ⇒ Object
factory method to create a UniqueDelayedJob by specifying a block that is executed and whose result is stored as a string to be evaled by delayed_job arguments:
- columns: hash of column names and values to insert into the delayed
jobs table in addition to the handler
NOTE: a block is expected
76 77 78 79 |
# File 'lib/delayed/unique_delayed_job.rb', line 76 def self.run_eval(columns = {}, &block) raise "missing a block in call to run_block" if !block_given? job = self.new(Delayed::EvaledJob.new(&block), columns) end |
.use_handler(handler, columns = {}) ⇒ Object
factory method to create a new UniqueDelayedJob from a delayed job handler object (see delayed job documentation for requirements)
arguments:
- handler: the delayed jobs handler object you're using
- columns: hash of column names and values to insert into the delayed
jobs table in addition to the handler
47 48 49 |
# File 'lib/delayed/unique_delayed_job.rb', line 47 def self.use_handler(handler, columns = {}) job = self.new(handler, columns) end |
Instance Method Details
#add_delayed_jobs_columns(new_columns) ⇒ Object
specify some additional columns to set in the delayed jobs table for this row. be sure that you’ve migrated to add these columns to the delayed jobs table. it is up to you to specify uniqueness constraints on any of the columns you’d like to use to prevent duplicate entries in the delayed jobs table. (it’s also fine for some of these columns to not have unique constraints, though this class will not prevent duplicate values for those and they’ll be for your use for other purposes.)
90 91 92 |
# File 'lib/delayed/unique_delayed_job.rb', line 90 def add_delayed_jobs_columns(new_columns) columns.merge! new_columns end |
#enqueue(priority = nil, run_at = nil) ⇒ Object
put the job on the delayed jobs queue. if there already is a row in the delayed jobs table with the same value in any of the unique columns (enforced in the db), then the row will not be inserted
return value:
- if a new delayed job is inserted, the job object is returned
- otherwise, returns nil
arguments:
priority:
run_at:
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/delayed/unique_delayed_job.rb', line 107 def enqueue(priority = nil, run_at = nil) if mark_all_locked_jobs_with_null && !columns.blank? null_setting_strings = [] columns.each_key do |c| null_setting_strings << "#{c.to_s} = NULL" end Delayed::Job.update_all(null_setting_strings.join("\n ,"), "locked_by IS NOT NULL") end cols_to_insert = columns cols_to_insert.merge! :priority => priority if priority cols_to_insert.merge! :run_at => run_at if run_at cols_to_insert.merge! :handler => handler job = nil # try to catch if this raises an exception because of a duplicate key # error this should work for mysql and postgresql which both have the # word 'duplicate' followed (not necessarily immediately) by 'key'. # ignoring case cause case differs between the two cases # if doesn't look like a dupe key error, then reraise the exception begin job = Delayed::Job.create(cols_to_insert) rescue => e if /(duplicate).*(key)/i !~ e. raise e end end return job end |