resque-scheduler 4.0.0 → 4.1.0
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.
Potentially problematic release.
This version of resque-scheduler might be problematic. Click here for more details.
- checksums.yaml +5 -13
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +32 -26
- data/.travis.yml +3 -8
- data/AUTHORS.md +3 -0
- data/README.md +14 -3
- data/lib/resque/scheduler.rb +12 -15
- data/lib/resque/scheduler/cli.rb +3 -1
- data/lib/resque/scheduler/configuration.rb +1 -1
- data/lib/resque/scheduler/delaying_extensions.rb +40 -11
- data/lib/resque/scheduler/env.rb +6 -18
- data/lib/resque/scheduler/server.rb +11 -5
- data/lib/resque/scheduler/server/views/delayed.erb +1 -2
- data/lib/resque/scheduler/server/views/search.erb +1 -2
- data/lib/resque/scheduler/signal_handling.rb +1 -1
- data/lib/resque/scheduler/util.rb +1 -3
- data/lib/resque/scheduler/version.rb +1 -1
- data/resque-scheduler.gemspec +5 -3
- data/test/cli_test.rb +5 -0
- data/test/delayed_queue_test.rb +277 -0
- data/test/scheduler_test.rb +18 -6
- data/test/test_helper.rb +7 -12
- data/test/util_test.rb +6 -0
- metadata +77 -49
- data/test/support/redis_instance.rb +0 -133
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZWZiZjMwYWRkMzRlOWQxYzViN2EzOGU0MDAwMTAzMTM4NTY5OTNkZQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b1c100ee487f2bbb303e4bd2efae46172ac89322
|
4
|
+
data.tar.gz: eccb0c76e7ed34839c8c585fa6751bc3c114f521
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZTkwMWJiYzljMGQ4MTI1MDY0NjA2ZWM1NGNjNjgwZDU1ZTIxZDk4N2ZmNjk4
|
11
|
-
ZWFjZjhkOTEyOWJmMDQ2YjBiY2MxMzBkYTg1ZjEzOGYzZDJhNDc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
OTQ4NjVhMjZjYTEwMDYyOGMwODBkMmQ2MGUyNDIzYTgyNjI1NmNhZjg2MzRm
|
14
|
-
NWI3Mjk2MGM4N2E2MjhkY2IwNjlkYjZlYWZmY2Q2ZTFhY2Y0ZWUxNmY3MmM4
|
15
|
-
ODkwZjE3MjljOTVlZWM2ZjZhZmRmMTQwYjM3ZDk0OGFmNTA3ODY=
|
6
|
+
metadata.gz: 9c8b1b82cf0d16eed3f711cfba27787232b4b282f8e329e98708f3a4a348a43b416acf74879165b3e1671b7a83c2d7a1aad25884ba5de5c64736c1a099a38696
|
7
|
+
data.tar.gz: ccd696fa8683b597401da6e0adbeaf5edf58ded176fd61a63ad8fbec9f6e5e052b0432e79b4c974f57778454553ce8bf4c25a5e024f3e23a44c807dc551ee2af
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-02-10 07:59:57 -0500 using RuboCop version 0.35.1.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -8,50 +9,55 @@
|
|
8
9
|
# Offense count: 2
|
9
10
|
# Configuration parameters: AllowSafeAssignment.
|
10
11
|
Lint/AssignmentInCondition:
|
11
|
-
|
12
|
+
Exclude:
|
13
|
+
- 'lib/resque/scheduler/delaying_extensions.rb'
|
14
|
+
- 'lib/resque/scheduler/env.rb'
|
12
15
|
|
13
|
-
# Offense count:
|
16
|
+
# Offense count: 15
|
14
17
|
Metrics/AbcSize:
|
15
|
-
Max:
|
18
|
+
Max: 36
|
16
19
|
|
17
|
-
# Offense count:
|
18
|
-
# Configuration parameters: CountComments.
|
19
|
-
Metrics/ClassLength:
|
20
|
-
Max: 105
|
21
|
-
|
22
|
-
# Offense count: 4
|
20
|
+
# Offense count: 3
|
23
21
|
Metrics/CyclomaticComplexity:
|
24
22
|
Max: 12
|
25
23
|
|
26
|
-
# Offense count:
|
24
|
+
# Offense count: 1
|
25
|
+
# Configuration parameters: AllowURI, URISchemes.
|
26
|
+
Metrics/LineLength:
|
27
|
+
Max: 87
|
28
|
+
|
29
|
+
# Offense count: 19
|
27
30
|
# Configuration parameters: CountComments.
|
28
31
|
Metrics/MethodLength:
|
29
32
|
Max: 34
|
30
33
|
|
34
|
+
# Offense count: 2
|
35
|
+
# Configuration parameters: CountComments.
|
36
|
+
Metrics/ModuleLength:
|
37
|
+
Max: 294
|
38
|
+
|
31
39
|
# Offense count: 1
|
32
40
|
Style/CaseEquality:
|
33
|
-
|
41
|
+
Exclude:
|
42
|
+
- 'lib/resque/scheduler.rb'
|
34
43
|
|
35
44
|
# Offense count: 1
|
36
45
|
Style/EachWithObject:
|
37
|
-
|
46
|
+
Exclude:
|
47
|
+
- 'lib/resque/scheduler.rb'
|
38
48
|
|
39
49
|
# Offense count: 3
|
40
50
|
# Configuration parameters: Exclude.
|
41
51
|
Style/FileName:
|
42
|
-
|
52
|
+
Exclude:
|
53
|
+
- 'examples/config/initializers/resque-web.rb'
|
54
|
+
- 'lib/resque-scheduler.rb'
|
55
|
+
- 'test/resque-web_test.rb'
|
43
56
|
|
44
57
|
# Offense count: 6
|
45
58
|
# Configuration parameters: MinBodyLength.
|
46
59
|
Style/GuardClause:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Style/IfUnlessModifier:
|
52
|
-
Enabled: false
|
53
|
-
|
54
|
-
# Offense count: 1
|
55
|
-
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
56
|
-
Style/Next:
|
57
|
-
Enabled: false
|
60
|
+
Exclude:
|
61
|
+
- 'lib/resque/scheduler.rb'
|
62
|
+
- 'lib/resque/scheduler/lock/basic.rb'
|
63
|
+
- 'test/support/redis_instance.rb'
|
data/.travis.yml
CHANGED
@@ -2,13 +2,13 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
rvm:
|
4
4
|
- 1.9.3
|
5
|
-
- 2.
|
5
|
+
- 2.3.0
|
6
6
|
- jruby-19mode
|
7
7
|
- rbx
|
8
8
|
env:
|
9
9
|
global:
|
10
|
-
- RESQUE_SCHEDULER_DISABLE_TEST_REDIS_SERVER=1
|
11
10
|
- JRUBY_OPTS='-Xcext.enabled=true'
|
11
|
+
- COVERAGE=1
|
12
12
|
matrix:
|
13
13
|
allow_failures:
|
14
14
|
- rvm: jruby-19mode
|
@@ -16,11 +16,6 @@ matrix:
|
|
16
16
|
services:
|
17
17
|
- redis-server
|
18
18
|
notifications:
|
19
|
-
email:
|
20
|
-
recipients:
|
21
|
-
- daniel.buch+resque-scheduler@gmail.com
|
22
|
-
on_success: change
|
23
|
-
on_failure: change
|
24
19
|
irc:
|
25
20
|
channels:
|
26
21
|
- 'chat.freenode.net#resque'
|
@@ -34,5 +29,5 @@ deploy:
|
|
34
29
|
on:
|
35
30
|
tags: true
|
36
31
|
repo: resque/resque-scheduler
|
37
|
-
rvm: 2.
|
32
|
+
rvm: 2.3.0
|
38
33
|
all_branches: true
|
data/AUTHORS.md
CHANGED
@@ -20,6 +20,7 @@ Resque Scheduler authors
|
|
20
20
|
- David Doan
|
21
21
|
- David Yang
|
22
22
|
- Denis Yagofarov
|
23
|
+
- dtaniwaki
|
23
24
|
- Evan Tahler
|
24
25
|
- Eugene Batogov
|
25
26
|
- Giovanni Cappellotto
|
@@ -36,6 +37,7 @@ Resque Scheduler authors
|
|
36
37
|
- Joshua Szmajda
|
37
38
|
- Justin Weiss
|
38
39
|
- Les Hill
|
40
|
+
- Luke Rodgers
|
39
41
|
- Manuel Meurer
|
40
42
|
- Matt Aimonetti
|
41
43
|
- Matt Simpson
|
@@ -56,6 +58,7 @@ Resque Scheduler authors
|
|
56
58
|
- Scott Francis
|
57
59
|
- Sebastian Kippe
|
58
60
|
- Spring MC
|
61
|
+
- tbprojects
|
59
62
|
- Tim Liner
|
60
63
|
- Tony Lewis
|
61
64
|
- Tom Crayford
|
data/README.md
CHANGED
@@ -91,7 +91,7 @@ namespace :resque do
|
|
91
91
|
require 'jobs'
|
92
92
|
end
|
93
93
|
|
94
|
-
task :
|
94
|
+
task :scheduler => :setup_schedule
|
95
95
|
end
|
96
96
|
```
|
97
97
|
|
@@ -180,7 +180,7 @@ a worker is available (just like any other resque job).
|
|
180
180
|
|
181
181
|
NOTE: The job does not fire **exactly** at the time supplied. Rather, once that
|
182
182
|
time is in the past, the job moves from the delayed queue to the actual resque
|
183
|
-
work queue and will be completed as workers
|
183
|
+
work queue and will be completed as workers are free to process it.
|
184
184
|
|
185
185
|
Also supported is `Resque.enqueue_at` which takes a timestamp to queue the
|
186
186
|
job, and `Resque.enqueue_at_with_queue` which takes both a timestamp and a
|
@@ -220,6 +220,17 @@ Resque.remove_delayed_selection { |args| args[0]['account_id'] == current_accoun
|
|
220
220
|
Resque.remove_delayed_selection { |args| args[0]['user_id'] == current_user.id }
|
221
221
|
```
|
222
222
|
|
223
|
+
If you need to enqueue immediately a delayed job based on some matching arguments, but don't wish to specify each argument from when the job was created, you can do like so:
|
224
|
+
|
225
|
+
``` ruby
|
226
|
+
# after you've enqueued a job like:
|
227
|
+
Resque.enqueue_at(5.days.from_now, SendFollowUpEmail, :account_id => current_account.id, :user_id => current_user.id)
|
228
|
+
# enqueue immediately jobs matching just the account:
|
229
|
+
Resque.enqueue_delayed_selection { |args| args[0]['account_id'] == current_account.id }
|
230
|
+
# or enqueue immediately jobs matching just the user:
|
231
|
+
Resque.enqueue_delayed_selection { |args| args[0]['user_id'] == current_user.id }
|
232
|
+
```
|
233
|
+
|
223
234
|
### Scheduled Jobs (Recurring Jobs)
|
224
235
|
|
225
236
|
Scheduled (or recurring) jobs are logically no different than a standard cron
|
@@ -439,7 +450,7 @@ end
|
|
439
450
|
*>= 2.0.1 only. Prior to 2.0.1, it is not recommended to run multiple resque-scheduler processes and will result in duplicate jobs.*
|
440
451
|
|
441
452
|
You may want to have resque-scheduler running on multiple machines for
|
442
|
-
|
453
|
+
redundancy. Electing a master and failover is built in and default. Simply
|
443
454
|
run resque-scheduler on as many machine as you want pointing to the same
|
444
455
|
redis instance and schedule. The scheduler processes will use redis to
|
445
456
|
elect a master process and detect failover when the master dies. Precautions are
|
data/lib/resque/scheduler.rb
CHANGED
@@ -129,23 +129,20 @@ module Resque
|
|
129
129
|
interval_defined = false
|
130
130
|
interval_types = %w(cron every)
|
131
131
|
interval_types.each do |interval_type|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
132
|
+
next unless !config[interval_type].nil? && config[interval_type].length > 0
|
133
|
+
args = optionizate_interval_value(config[interval_type])
|
134
|
+
args = [args, nil, job: true] if args.is_a?(::String)
|
135
|
+
|
136
|
+
job = rufus_scheduler.send(interval_type, *args) do
|
137
|
+
if master?
|
138
|
+
log! "queueing #{config['class']} (#{name})"
|
139
|
+
Resque.last_enqueued_at(name, Time.now.to_s)
|
140
|
+
handle_errors { enqueue_from_config(config) }
|
136
141
|
end
|
137
|
-
|
138
|
-
job = rufus_scheduler.send(interval_type, *args) do
|
139
|
-
if master?
|
140
|
-
log! "queueing #{config['class']} (#{name})"
|
141
|
-
Resque.last_enqueued_at(name, Time.now.to_s)
|
142
|
-
handle_errors { enqueue_from_config(config) }
|
143
|
-
end
|
144
|
-
end
|
145
|
-
@scheduled_jobs[name] = job
|
146
|
-
interval_defined = true
|
147
|
-
break
|
148
142
|
end
|
143
|
+
@scheduled_jobs[name] = job
|
144
|
+
interval_defined = true
|
145
|
+
break
|
149
146
|
end
|
150
147
|
unless interval_defined
|
151
148
|
log! "no #{interval_types.join(' / ')} found for " \
|
data/lib/resque/scheduler/cli.rb
CHANGED
@@ -136,7 +136,9 @@ module Resque
|
|
136
136
|
|
137
137
|
def options
|
138
138
|
@options ||= {}.tap do |o|
|
139
|
-
CLI_OPTIONS_ENV_MAPPING.
|
139
|
+
CLI_OPTIONS_ENV_MAPPING.each do |key, envvar|
|
140
|
+
o[key] = env[envvar] if env.include?(envvar)
|
141
|
+
end
|
140
142
|
end
|
141
143
|
end
|
142
144
|
end
|
@@ -158,7 +158,35 @@ module Resque
|
|
158
158
|
def remove_delayed_selection(klass = nil)
|
159
159
|
fail ArgumentError, 'Please supply a block' unless block_given?
|
160
160
|
|
161
|
-
|
161
|
+
found_jobs = find_delayed_selection(klass) { |args| yield(args) }
|
162
|
+
found_jobs.reduce(0) do |sum, encoded_job|
|
163
|
+
sum + remove_delayed_job(encoded_job)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Given a block, enqueue jobs now that return true from a block
|
168
|
+
#
|
169
|
+
# This allows for enqueuing of delayed jobs that have arguments matching
|
170
|
+
# certain criteria
|
171
|
+
def enqueue_delayed_selection(klass = nil)
|
172
|
+
fail ArgumentError, 'Please supply a block' unless block_given?
|
173
|
+
|
174
|
+
found_jobs = find_delayed_selection(klass) { |args| yield(args) }
|
175
|
+
found_jobs.reduce(0) do |sum, encoded_job|
|
176
|
+
decoded_job = decode(encoded_job)
|
177
|
+
klass = Util.constantize(decoded_job['class'])
|
178
|
+
sum + enqueue_delayed(klass, *decoded_job['args'])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Given a block, find jobs that return true from a block
|
183
|
+
#
|
184
|
+
# This allows for finding of delayed jobs that have arguments matching
|
185
|
+
# certain criteria
|
186
|
+
def find_delayed_selection(klass = nil, &block)
|
187
|
+
fail ArgumentError, 'Please supply a block' unless block_given?
|
188
|
+
|
189
|
+
found_jobs = []
|
162
190
|
start = nil
|
163
191
|
while start = search_first_delayed_timestamp_in_range(start, nil)
|
164
192
|
job = "delayed:#{start}"
|
@@ -167,19 +195,13 @@ module Resque
|
|
167
195
|
while index >= 0
|
168
196
|
payload = Resque.redis.lindex(job, index)
|
169
197
|
decoded_payload = decode(payload)
|
170
|
-
|
171
|
-
|
172
|
-
if relevant_class && yield(decoded_payload['args'])
|
173
|
-
removed = remove_delayed_job(payload)
|
174
|
-
destroyed += removed
|
175
|
-
index -= removed
|
176
|
-
else
|
177
|
-
index -= 1
|
198
|
+
if payload_matches_selection?(decoded_payload, klass, &block)
|
199
|
+
found_jobs.push(payload)
|
178
200
|
end
|
201
|
+
index -= 1
|
179
202
|
end
|
180
203
|
end
|
181
|
-
|
182
|
-
destroyed
|
204
|
+
found_jobs
|
183
205
|
end
|
184
206
|
|
185
207
|
# Given a timestamp and job (klass + args) it removes all instances and
|
@@ -283,6 +305,13 @@ module Resque
|
|
283
305
|
timestamp.to_i unless timestamp.nil?
|
284
306
|
end
|
285
307
|
|
308
|
+
def payload_matches_selection?(decoded_payload, klass)
|
309
|
+
return false if decoded_payload.nil?
|
310
|
+
job_class = decoded_payload['class']
|
311
|
+
relevant_class = (klass.nil? || klass.to_s == job_class)
|
312
|
+
relevant_class && yield(decoded_payload['args'])
|
313
|
+
end
|
314
|
+
|
286
315
|
def plugin
|
287
316
|
Resque::Scheduler::Plugin
|
288
317
|
end
|
data/lib/resque/scheduler/env.rb
CHANGED
@@ -56,33 +56,21 @@ module Resque
|
|
56
56
|
|
57
57
|
def setup_scheduler_configuration
|
58
58
|
Resque::Scheduler.configure do |c|
|
59
|
-
if options.key?(:app_name)
|
60
|
-
c.app_name = options[:app_name]
|
61
|
-
end
|
59
|
+
c.app_name = options[:app_name] if options.key?(:app_name)
|
62
60
|
|
63
|
-
if options.key?(:dynamic)
|
64
|
-
c.dynamic = !!options[:dynamic]
|
65
|
-
end
|
61
|
+
c.dynamic = !!options[:dynamic] if options.key?(:dynamic)
|
66
62
|
|
67
|
-
if options.key(:env)
|
68
|
-
c.env = options[:env]
|
69
|
-
end
|
63
|
+
c.env = options[:env] if options.key(:env)
|
70
64
|
|
71
|
-
if options.key?(:logfile)
|
72
|
-
c.logfile = options[:logfile]
|
73
|
-
end
|
65
|
+
c.logfile = options[:logfile] if options.key?(:logfile)
|
74
66
|
|
75
|
-
if options.key?(:logformat)
|
76
|
-
c.logformat = options[:logformat]
|
77
|
-
end
|
67
|
+
c.logformat = options[:logformat] if options.key?(:logformat)
|
78
68
|
|
79
69
|
if psleep = options[:poll_sleep_amount] && !psleep.nil?
|
80
70
|
c.poll_sleep_amount = Float(psleep)
|
81
71
|
end
|
82
72
|
|
83
|
-
if options.key?(:verbose)
|
84
|
-
c.verbose = !!options[:verbose]
|
85
|
-
end
|
73
|
+
c.verbose = !!options[:verbose] if options.key?(:verbose)
|
86
74
|
end
|
87
75
|
end
|
88
76
|
|
@@ -1,12 +1,17 @@
|
|
1
1
|
# vim:fileencoding=utf-8
|
2
2
|
require 'resque-scheduler'
|
3
3
|
require 'resque/server'
|
4
|
+
require 'tilt/erb'
|
4
5
|
require 'json'
|
5
6
|
|
6
7
|
# Extend Resque::Server to add tabs
|
7
8
|
module Resque
|
8
9
|
module Scheduler
|
9
10
|
module Server
|
11
|
+
unless defined?(::Resque::Scheduler::Server::VIEW_PATH)
|
12
|
+
VIEW_PATH = File.join(File.dirname(__FILE__), 'server', 'views')
|
13
|
+
end
|
14
|
+
|
10
15
|
def self.included(base)
|
11
16
|
base.class_eval do
|
12
17
|
helpers { include HelperMethods }
|
@@ -121,10 +126,6 @@ module Resque
|
|
121
126
|
end
|
122
127
|
|
123
128
|
module HelperMethods
|
124
|
-
def render_partial(partial)
|
125
|
-
erb partial, layout: false
|
126
|
-
end
|
127
|
-
|
128
129
|
def format_time(t)
|
129
130
|
t.strftime('%Y-%m-%d %H:%M:%S %z')
|
130
131
|
end
|
@@ -175,7 +176,7 @@ module Resque
|
|
175
176
|
|
176
177
|
s << ' ('
|
177
178
|
meta = every.last.map do |key, value|
|
178
|
-
"#{key.to_s.
|
179
|
+
"#{key.to_s.tr('_', ' ')} #{value}"
|
179
180
|
end
|
180
181
|
s << meta.join(', ') << ')'
|
181
182
|
end
|
@@ -203,6 +204,11 @@ module Resque
|
|
203
204
|
Resque.schedule[name]['rails_env']
|
204
205
|
end
|
205
206
|
|
207
|
+
def scheduler_view(filename, options = {}, locals = {})
|
208
|
+
source = File.read(File.join(VIEW_PATH, "#{filename}.erb"))
|
209
|
+
erb source, options, locals
|
210
|
+
end
|
211
|
+
|
206
212
|
private
|
207
213
|
|
208
214
|
def working_jobs_for_worker(worker)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<h1>Delayed Jobs</h1>
|
2
2
|
<%- size = resque.delayed_queue_schedule_size %>
|
3
3
|
|
4
|
-
<%=
|
4
|
+
<%= scheduler_view :search_form, layout: false %>
|
5
5
|
|
6
6
|
<p class='intro'>
|
7
7
|
This list below contains the timestamps for scheduled delayed jobs.
|
@@ -57,4 +57,3 @@
|
|
57
57
|
<% end %>
|
58
58
|
|
59
59
|
<%= partial :next_more, :start => start, :size => size %>
|
60
|
-
|