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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YWQ5NjY1MDg2NGNmODVkNWQxZDNmOWJjNzAxMWRjMGNjZWFhM2RiNg==
5
- data.tar.gz: !binary |-
6
- ZWZiZjMwYWRkMzRlOWQxYzViN2EzOGU0MDAwMTAzMTM4NTY5OTNkZQ==
2
+ SHA1:
3
+ metadata.gz: b1c100ee487f2bbb303e4bd2efae46172ac89322
4
+ data.tar.gz: eccb0c76e7ed34839c8c585fa6751bc3c114f521
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YWY0MjRlNjcyOWZjODM5YWNlYjFlNDM5ZGU1NjFjYmQwZDQ2NDY0YWFiMmJh
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
@@ -14,3 +14,5 @@ Style/DoubleNegation:
14
14
  Enabled: false
15
15
  Metrics/PerceivedComplexity:
16
16
  Enabled: false
17
+ Metrics/ClassLength:
18
+ Max: 110
data/.rubocop_todo.yml CHANGED
@@ -1,5 +1,6 @@
1
- # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2014-12-21 12:37:35 -0500 using RuboCop version 0.28.0.
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
- Enabled: false
12
+ Exclude:
13
+ - 'lib/resque/scheduler/delaying_extensions.rb'
14
+ - 'lib/resque/scheduler/env.rb'
12
15
 
13
- # Offense count: 16
16
+ # Offense count: 15
14
17
  Metrics/AbcSize:
15
- Max: 42
18
+ Max: 36
16
19
 
17
- # Offense count: 2
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: 18
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
- Enabled: false
41
+ Exclude:
42
+ - 'lib/resque/scheduler.rb'
34
43
 
35
44
  # Offense count: 1
36
45
  Style/EachWithObject:
37
- Enabled: false
46
+ Exclude:
47
+ - 'lib/resque/scheduler.rb'
38
48
 
39
49
  # Offense count: 3
40
50
  # Configuration parameters: Exclude.
41
51
  Style/FileName:
42
- Enabled: false
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
- Enabled: false
48
-
49
- # Offense count: 6
50
- # Configuration parameters: MaxLineLength.
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.1.5
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.1.5
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 :scheduler_setup => :setup_schedule
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 as free to process it.
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
- redudancy. Electing a master and failover is built in and default. Simply
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
@@ -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
- if !config[interval_type].nil? && config[interval_type].length > 0
133
- args = optionizate_interval_value(config[interval_type])
134
- if args.is_a?(::String)
135
- args = [args, nil, job: true]
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 " \
@@ -136,7 +136,9 @@ module Resque
136
136
 
137
137
  def options
138
138
  @options ||= {}.tap do |o|
139
- CLI_OPTIONS_ENV_MAPPING.map { |key, envvar| o[key] = env[envvar] }
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
@@ -13,7 +13,7 @@ module Resque
13
13
 
14
14
  def env
15
15
  return @env if @env
16
- @env ||= Rails.env if defined?(Rails)
16
+ @env ||= Rails.env if defined?(Rails) && Rails.respond_to?(:env)
17
17
  @env ||= ENV['RAILS_ENV']
18
18
  @env
19
19
  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
- destroyed = 0
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
- job_class = decoded_payload['class']
171
- relevant_class = (klass.nil? || klass.to_s == job_class)
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
@@ -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.gsub(/_/, ' ')} #{value}"
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
- <%= render_partial File.read(File.join(File.dirname(__FILE__), 'server/views/search_form.erb')) %>
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
-