delayed_job_recurring 0.3.4 → 0.3.9
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.
- checksums.yaml +5 -5
- data/README.md +48 -2
- data/lib/delayed/recurring_job.rb +43 -54
- metadata +27 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d2df13749a11ec5a5a5fef3f60eb7c7a1216e13a6b93a6e084392a30b0fabefd
|
4
|
+
data.tar.gz: 98bbe52c01ef1a79e4ce2c512a47d91e4a9380b8d119fc05605e13a27f805425
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec8ae92ce900948c73831b5b965e603032ee645e134b410af15f1e1b5392b5b3630252acac34ced89e3ff71d1334a37b7bd3fed212dabcc47d2ab37ee44d1294
|
7
|
+
data.tar.gz: bb8f9c77c3d0417b1e35861d7f81c8e8c82eb10963bdb32ffeef0b14f87cdfa2c8430259ddd8b7d494922434f6d38b1f8cb9f587f10373155218adec14cf36ae
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# delayed\_job\_recurring
|
2
|
+
[](https://travis-ci.org/amitree/delayed_job_recurring)
|
2
3
|
|
3
4
|
Extends delayed\_job to support recurring jobs.
|
4
5
|
|
@@ -27,12 +28,41 @@ class MyTask
|
|
27
28
|
end
|
28
29
|
```
|
29
30
|
|
30
|
-
|
31
|
+
Finally, schedule it:
|
31
32
|
|
32
33
|
```ruby
|
33
34
|
MyTask.schedule! # run every day at 11am Pacific time (accounting for daylight savings)
|
34
35
|
```
|
35
36
|
|
37
|
+
The best practice is to add your `MyTask.schedule!` lines to a rake file, e.g.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# lib/tasks/recurring_jobs.rake
|
41
|
+
|
42
|
+
namespace :recurring do
|
43
|
+
task init: :environment do
|
44
|
+
MyTask.schedule!
|
45
|
+
MyOtherTask.schedule!
|
46
|
+
|
47
|
+
if Rails.env.production?
|
48
|
+
MyProductionOnlyTask.schedule!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
and invoke this job by running `rake recurring:init` on each deployment.
|
55
|
+
|
56
|
+
Alternatively, if your app only has one instance running, you can put your
|
57
|
+
`schedule!` calls into an initializer, and then your jobs will be automatically
|
58
|
+
scheduled when your app starts. However, if you have more than one instance of
|
59
|
+
your app running in production, this will lead to a race condition and you will
|
60
|
+
end up with duplicate recurring jobs in the queue.
|
61
|
+
|
62
|
+
## ActiveJob
|
63
|
+
|
64
|
+
Note: your task class should **not** inherit from ActiveJob::Base.
|
65
|
+
|
36
66
|
## Advanced usage
|
37
67
|
|
38
68
|
### Passing options to schedule
|
@@ -44,7 +74,7 @@ MyTask.schedule(run_at: '12:00')
|
|
44
74
|
### Running at multiples times each day
|
45
75
|
|
46
76
|
```ruby
|
47
|
-
MyTask.schedule(run_every: 1.day, run_at: ['11:00', '6:00pm']
|
77
|
+
MyTask.schedule(run_every: 1.day, run_at: ['11:00', '6:00pm'])
|
48
78
|
```
|
49
79
|
|
50
80
|
### Running on specific days of the week
|
@@ -53,6 +83,22 @@ MyTask.schedule(run_every: 1.day, run_at: ['11:00', '6:00pm']
|
|
53
83
|
MyTask.schedule(run_every: 1.week, run_at: ['sunday 8:00am', 'wednesday 8:00am'])
|
54
84
|
```
|
55
85
|
|
86
|
+
### Scheduling multiple jobs of same class
|
87
|
+
|
88
|
+
By default, before scheduling a new job, the old jobs scheduled with the same class will be unscheduled.
|
89
|
+
|
90
|
+
To schedule multiple jobs with same class, pass an unique matching param `job_matching_param` and value for that matching param in each job as below:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
MyTask.schedule(run_at: '12:00', job_matching_param: 'schedule_id', schedule_id: 2)
|
94
|
+
```
|
95
|
+
|
96
|
+
This allows you to schedule multiple jobs with same class if value of the unique matching param(which is `schedule_id` in above example) is different in each job.
|
97
|
+
|
56
98
|
## Thanks!
|
57
99
|
|
58
100
|
Many thanks to @ginjo and @kares for their work! This code was derived from https://gist.github.com/ginjo/3688965.
|
101
|
+
|
102
|
+
## Contributing
|
103
|
+
|
104
|
+
[](https://www.codetriage.com/amitree/delayed_job_recurring)
|
@@ -23,13 +23,17 @@ module Delayed
|
|
23
23
|
|
24
24
|
# Schedule this "repeating" job
|
25
25
|
def schedule! options = {}
|
26
|
-
options = options.dup
|
26
|
+
options = options.dup.reverse_merge(@schedule_options || {})
|
27
|
+
|
28
|
+
if options[:new_instance] && !options.delete(:reentry)
|
29
|
+
return self.class.new.schedule! options.merge(reentry: true)
|
30
|
+
end
|
27
31
|
|
28
32
|
if run_every = options.delete(:run_every)
|
29
33
|
options[:run_interval] = serialize_duration(run_every)
|
30
34
|
end
|
31
35
|
|
32
|
-
@schedule_options = options.reverse_merge(
|
36
|
+
@schedule_options = options.reverse_merge(
|
33
37
|
run_at: self.class.run_at,
|
34
38
|
timezone: self.class.timezone,
|
35
39
|
run_interval: serialize_duration(self.class.run_every),
|
@@ -40,10 +44,13 @@ module Delayed
|
|
40
44
|
enqueue_opts = { priority: @schedule_options[:priority], run_at: next_run_time }
|
41
45
|
enqueue_opts[:queue] = @schedule_options[:queue] if @schedule_options[:queue]
|
42
46
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
Delayed::Job.transaction do
|
48
|
+
self.class.jobs(@schedule_options).destroy_all
|
49
|
+
if Gem.loaded_specs['delayed_job'].version.to_s.first.to_i < 3
|
50
|
+
Delayed::Job.enqueue self, enqueue_opts[:priority], enqueue_opts[:run_at]
|
51
|
+
else
|
52
|
+
Delayed::Job.enqueue self, enqueue_opts
|
53
|
+
end
|
47
54
|
end
|
48
55
|
end
|
49
56
|
|
@@ -157,77 +164,59 @@ module Delayed
|
|
157
164
|
end
|
158
165
|
|
159
166
|
# Show all jobs for this schedule
|
160
|
-
def jobs
|
161
|
-
|
167
|
+
def jobs(options = {})
|
168
|
+
options = options.with_indifferent_access
|
169
|
+
|
170
|
+
# Construct dynamic query with 'job_matching_param' if present
|
171
|
+
query = ["((handler LIKE ?) OR (handler LIKE ?))", "--- !ruby/object:#{name} %", "--- !ruby/object:#{name}\n%"]
|
172
|
+
if options[:job_matching_param].present?
|
173
|
+
matching_key = options[:job_matching_param]
|
174
|
+
matching_value = options[matching_key]
|
175
|
+
matching_yaml = yaml_quote(matching_value)
|
176
|
+
query[0] = "#{query[0]} AND handler LIKE ?"
|
177
|
+
query << "%#{matching_key}: #{matching_yaml}%"
|
178
|
+
end
|
179
|
+
|
180
|
+
::Delayed::Job.where(query)
|
162
181
|
end
|
163
182
|
|
164
183
|
# Remove all jobs for this schedule (Stop the schedule)
|
165
|
-
def unschedule
|
166
|
-
jobs.each{|j| j.destroy}
|
184
|
+
def unschedule(options = {})
|
185
|
+
jobs(options).each{|j| j.destroy}
|
167
186
|
end
|
168
187
|
|
169
188
|
# Main interface to start this schedule (adds it to the jobs table).
|
170
189
|
# Pass in a time to run the first job (nil runs the first job at run_interval from now).
|
171
190
|
def schedule(options = {})
|
172
|
-
schedule!(options) unless scheduled?
|
191
|
+
schedule!(options) unless scheduled?(options)
|
173
192
|
end
|
174
193
|
|
175
194
|
def schedule!(options = {})
|
176
195
|
return unless Delayed::Worker.delay_jobs
|
177
|
-
unschedule
|
178
|
-
new.schedule!(options)
|
196
|
+
unschedule(options)
|
197
|
+
new.schedule!(options.merge(new_instance: true))
|
179
198
|
end
|
180
199
|
|
181
|
-
def scheduled?
|
182
|
-
jobs.count > 0
|
200
|
+
def scheduled?(options = {})
|
201
|
+
jobs(options).count > 0
|
183
202
|
end
|
184
203
|
|
185
204
|
def inherited(subclass)
|
186
|
-
|
205
|
+
[:@run_at, :@run_interval, :@tz, :@priority].each do |var|
|
187
206
|
next unless instance_variable_defined? var
|
188
207
|
subclass.instance_variable_set var, self.instance_variable_get(var)
|
189
208
|
subclass.instance_variable_set "#{var}_inherited", true
|
190
209
|
end
|
191
210
|
end
|
192
211
|
|
212
|
+
private
|
213
|
+
def yaml_quote(value)
|
214
|
+
# In order to ensure matching indentation, place the element inside a
|
215
|
+
# two-level hash (the first level mimicking 'schedule_options', the second
|
216
|
+
# for #{job_matching_param}), and strip out the leading "---\n:a:\n :a: "
|
217
|
+
# but keep the trailing newline.
|
218
|
+
({a: {a: value}}).to_yaml[14..-1]
|
219
|
+
end
|
193
220
|
end # ClassMethods
|
194
221
|
end # RecurringJob
|
195
|
-
|
196
|
-
module Task
|
197
|
-
# Creates a new class wrapper around a block of code to be scheduled.
|
198
|
-
def self.new(name, options, &block)
|
199
|
-
task_class = Class.new
|
200
|
-
task_class.class_eval do
|
201
|
-
include Delayed::RecurringJob
|
202
|
-
|
203
|
-
def display_name
|
204
|
-
self.class.name
|
205
|
-
end
|
206
|
-
|
207
|
-
def perform
|
208
|
-
block.call
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
Object.const_set(name, task_class) if name
|
213
|
-
task_class.schedule(options)
|
214
|
-
return task_class
|
215
|
-
end
|
216
|
-
|
217
|
-
# Schedule a block of code on-the-fly.
|
218
|
-
# This is a friendly wrapper for using Task.new without an explicit constant assignment.
|
219
|
-
# Delayed::Task.schedule('MyNewTask', run_every: 10.minutes, run_at: 1.minute.from_now){do_some_stuff_here}
|
220
|
-
# or
|
221
|
-
# Delayed::Task.schedule(run_every: 10.minutes, run_at: 1.minute.from_now){do_some_stuff_here}
|
222
|
-
def self.schedule(name_or_options={}, options={}, &block)
|
223
|
-
case name_or_options
|
224
|
-
when Hash
|
225
|
-
name, options = nil, name_or_options
|
226
|
-
else
|
227
|
-
name = name_or_options
|
228
|
-
end
|
229
|
-
|
230
|
-
self.new name, options, &block
|
231
|
-
end
|
232
|
-
end # Task
|
233
222
|
end # Delayed
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delayed_job_recurring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Novak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,34 +24,48 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rspec
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - '='
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
47
|
+
version: 3.6.0
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - '='
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
54
|
+
version: 3.6.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec-rails
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - '='
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: 3.
|
61
|
+
version: 3.6.1
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - '='
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: 3.
|
68
|
+
version: 3.6.1
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sqlite3
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,28 +114,28 @@ dependencies:
|
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
117
|
+
version: '3.0'
|
104
118
|
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
124
|
+
version: '3.0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: delayed_job_active_record
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
131
|
+
version: '0'
|
118
132
|
type: :runtime
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
138
|
+
version: '0'
|
125
139
|
description: Extends delayed_job to support recurring jobs, including timezone support
|
126
140
|
email: engineering@amitree.com
|
127
141
|
executables: []
|
@@ -142,17 +156,16 @@ require_paths:
|
|
142
156
|
- lib
|
143
157
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
158
|
requirements:
|
145
|
-
- - "
|
159
|
+
- - ">"
|
146
160
|
- !ruby/object:Gem::Version
|
147
|
-
version: '
|
161
|
+
version: '1.9'
|
148
162
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
164
|
- - ">="
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0'
|
153
167
|
requirements: []
|
154
|
-
|
155
|
-
rubygems_version: 2.2.2
|
168
|
+
rubygems_version: 3.0.6
|
156
169
|
signing_key:
|
157
170
|
specification_version: 4
|
158
171
|
summary: Recurring jobs for delayed_job
|