unique_delayed_job 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +30 -0
- data/lib/unique_delayed_job.rb +116 -0
- data/unique_delayed_job.gemspec +49 -0
- metadata +69 -0
data/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= unique_delayed_job
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
|
5
|
+
You must have delayed_job installed as a gem or plugin to use this class.
|
6
|
+
|
7
|
+
Class for creating delayed jobs that can be de-duped with existing delayed jobs
|
8
|
+
already in the delayed jobs table. You just specify some additional columns on
|
9
|
+
your delayed_jobs table and set them to have uniqueness constraints. Then
|
10
|
+
specify these column values when you create a UniqueDelayedJob and if a
|
11
|
+
duplicate key is raised on insert, then the insert will just be ignored. There
|
12
|
+
are factory methods for creating a delayed job in the following ways:
|
13
|
+
* with a delayed job handler class (one that responds to perform())
|
14
|
+
* with an object, method and method arguments
|
15
|
+
* with a code block
|
16
|
+
|
17
|
+
== Examples
|
18
|
+
|
19
|
+
# use a custom handler
|
20
|
+
job = Delayed::UniqueDelayedJob.use_handler(MyHandlerClass.new( ...), :user_id => 123)
|
21
|
+
job.enqueue # use default priority and run_at
|
22
|
+
|
23
|
+
# use a method call (similar to using send_later on the object)
|
24
|
+
record = MyActiveRecord.find(1)
|
25
|
+
job = Delayed::UniqueDelayedJob.call_method(record, :a_method, [arg1, arg2], :user_id => 123)
|
26
|
+
job.enqueue(1) # use priority of 1
|
27
|
+
|
28
|
+
# use a code block
|
29
|
+
job = Delayed::UniqueDelayedJob.run_block(:user_id => 123) { run_some_code }
|
30
|
+
job.enqueue(2, 1.hour.from_now) # priority 1, run at 1 hour from now
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Delayed
|
2
|
+
|
3
|
+
# allows for specifying additional columns on the delayed_jobs table to help
|
4
|
+
# prevent duplicate delayed jobs from being entered into the queue...but still
|
5
|
+
# keep an easy interface to enqueuing delayed jobs
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
class UniqueDelayedJob
|
8
|
+
|
9
|
+
# factory method to create a new UniqueDelayedJob from a delayed job handler
|
10
|
+
# object (see delayed job documentation for requirements)
|
11
|
+
#
|
12
|
+
# arguments:
|
13
|
+
# - handler: the delayed jobs handler object you're using
|
14
|
+
# - columns: hash of column names and values to insert into the delayed
|
15
|
+
# jobs table in addition to the handler
|
16
|
+
#---------------------------------------------------------------------------
|
17
|
+
def self.use_handler(handler, columns = {})
|
18
|
+
job = self.new
|
19
|
+
job.handler = handler
|
20
|
+
|
21
|
+
job
|
22
|
+
end
|
23
|
+
|
24
|
+
# factory method to create a new UniqueDelayedJob by specifying a method ton
|
25
|
+
# call. will use delayed jobs' PerformableMethod class to enqueue the job
|
26
|
+
#
|
27
|
+
# arguments:
|
28
|
+
# - object: the object (or class or module) on which to call the method
|
29
|
+
# - method: the method to call (specify a symbol or string)
|
30
|
+
# - args_arr: an array of arguments to pass in the method call)
|
31
|
+
# - columns: hash of column names and values to insert into the delayed
|
32
|
+
# jobs table in addition to the handler
|
33
|
+
#---------------------------------------------------------------------------
|
34
|
+
def self.call_method(object, method, args_arr, columns = {})
|
35
|
+
job = self.new
|
36
|
+
job.handler = Delayed::PerformableMethod.new(object, method, args_arr)
|
37
|
+
|
38
|
+
job
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# factory method to create a UniqueDelayedJob by specifying a block to
|
43
|
+
# execute asynchronously
|
44
|
+
# arguments:
|
45
|
+
# - columns: hash of column names and values to insert into the delayed
|
46
|
+
# jobs table in addition to the handler
|
47
|
+
# NOTE: a block is expected
|
48
|
+
#---------------------------------------------------------------------------
|
49
|
+
def self.run_block(columns = {}, &block)
|
50
|
+
raise "missing a block in call to run_block" if !block_given?
|
51
|
+
job = self.new
|
52
|
+
job.handler = Delayed::EvaledJob.new(&block)
|
53
|
+
|
54
|
+
job
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# specify some additional columns to set in the delayed jobs table for this
|
59
|
+
# row. be sure that you've migrated to add these columns to the delayed jobs
|
60
|
+
# table. it is up to you to specify uniqueness constraints on any of the
|
61
|
+
# columns you'd like to use to prevent duplicate entries in the delayed jobs
|
62
|
+
# table. (it's also fine for some of these columns to not have unique
|
63
|
+
# constraints, though this class will not prevent duplicate values for those
|
64
|
+
# and they'll be for your use for other purposes.)
|
65
|
+
#---------------------------------------------------------------------------
|
66
|
+
def add_delayed_jobs_columns(new_columns)
|
67
|
+
columns.merge! new_columns
|
68
|
+
end
|
69
|
+
|
70
|
+
# put the job on the delayed jobs queue. if there already is a row in the
|
71
|
+
# delayed jobs table with the same value in any of the unique columns
|
72
|
+
# (enforced in the db), then the row will not be inserted
|
73
|
+
#
|
74
|
+
# arguments:
|
75
|
+
# priority:
|
76
|
+
# run_at:
|
77
|
+
#---------------------------------------------------------------------------
|
78
|
+
def enqueue(priority = nil, run_at = nil)
|
79
|
+
cols_to_insert = columns
|
80
|
+
cols_to_insert.merge! :priority => priority if priority
|
81
|
+
cols_to_insert.merge! :run_at => run_at if run_at
|
82
|
+
cols_to_insert.merge! :handler => handler
|
83
|
+
|
84
|
+
# try to catch if this raises an exception because of a duplicate key
|
85
|
+
# error this should work for mysql and postgresql which both have the
|
86
|
+
# word 'duplicate' followed (not necessarily immediately) by 'key'.
|
87
|
+
# ignoring case cause case differs between the two cases
|
88
|
+
# if doesn't look like a dupe key error, then reraise the exception
|
89
|
+
begin
|
90
|
+
Delayed::Job.create(cols_to_insert)
|
91
|
+
rescue => e
|
92
|
+
if /(duplicate).*(key)/i !~ e.message
|
93
|
+
raise e
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
attr_accessor :columns
|
100
|
+
|
101
|
+
protected
|
102
|
+
|
103
|
+
attr_accessor :handler
|
104
|
+
|
105
|
+
|
106
|
+
# constructor used by the factory methods
|
107
|
+
#---------------------------------------------------------------------------
|
108
|
+
def initialize(handler, columns = {})
|
109
|
+
@handler = nil
|
110
|
+
@call_method = { :method => nil, args => nil }
|
111
|
+
@columns = {}
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{unique_delayed_job}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Brian Percival"]
|
12
|
+
s.date = %q{2009-11-18}
|
13
|
+
s.description = %q{Class for creating delayed jobs that can be de-duped with existing delayed jobs
|
14
|
+
already in the delayed jobs table. You just specify some additional columns on
|
15
|
+
your delayed_jobs table and set them to have uniqueness constraints. Then
|
16
|
+
specify these column values when you create a UniqueDelayedJob and if a
|
17
|
+
duplicate key is raised on insert, then the insert will just be ignored. There
|
18
|
+
are factory methods for creating a delayed job in the following ways:
|
19
|
+
* with a delayed job handler class (one that responds to perform())
|
20
|
+
* with an object, method and method arguments
|
21
|
+
* with a code block
|
22
|
+
|
23
|
+
NOTE: you must have delayed_job installed as a gem or plugin
|
24
|
+
}
|
25
|
+
s.email = %q{percivalatumamibuddotcom}
|
26
|
+
s.extra_rdoc_files = [
|
27
|
+
"README"
|
28
|
+
]
|
29
|
+
s.files = [
|
30
|
+
"lib/unique_delayed_job.rb",
|
31
|
+
"unique_delayed_job.gemspec"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/bmpercy/unique_delayed_job}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Class for inserting delayed jobs without duplication}
|
38
|
+
|
39
|
+
if s.respond_to? :specification_version then
|
40
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
44
|
+
else
|
45
|
+
end
|
46
|
+
else
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unique_delayed_job
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Percival
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-18 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: |
|
17
|
+
Class for creating delayed jobs that can be de-duped with existing delayed jobs
|
18
|
+
already in the delayed jobs table. You just specify some additional columns on
|
19
|
+
your delayed_jobs table and set them to have uniqueness constraints. Then
|
20
|
+
specify these column values when you create a UniqueDelayedJob and if a
|
21
|
+
duplicate key is raised on insert, then the insert will just be ignored. There
|
22
|
+
are factory methods for creating a delayed job in the following ways:
|
23
|
+
* with a delayed job handler class (one that responds to perform())
|
24
|
+
* with an object, method and method arguments
|
25
|
+
* with a code block
|
26
|
+
|
27
|
+
NOTE: you must have delayed_job installed as a gem or plugin
|
28
|
+
|
29
|
+
email: percivalatumamibuddotcom
|
30
|
+
executables: []
|
31
|
+
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files:
|
35
|
+
- README
|
36
|
+
files:
|
37
|
+
- lib/unique_delayed_job.rb
|
38
|
+
- unique_delayed_job.gemspec
|
39
|
+
- README
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/bmpercy/unique_delayed_job
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Class for inserting delayed jobs without duplication
|
68
|
+
test_files: []
|
69
|
+
|