resque-scheduler 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
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
|
-
|