resque-scheduler 2.0.0.e → 2.0.0.g
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.
- data/.gitignore +1 -0
- data/Gemfile +7 -0
- data/HISTORY.md +9 -1
- data/README.markdown +51 -20
- data/Rakefile +12 -5
- data/lib/resque/scheduler.rb +15 -11
- data/lib/resque_scheduler.rb +35 -3
- data/lib/resque_scheduler/tasks.rb +7 -0
- data/lib/resque_scheduler/version.rb +1 -1
- data/resque-scheduler.gemspec +4 -5
- data/test/delayed_queue_test.rb +93 -33
- data/test/scheduler_args_test.rb +64 -1
- data/test/scheduler_hooks_test.rb +52 -0
- data/test/scheduler_test.rb +16 -83
- data/test/test_helper.rb +4 -0
- metadata +13 -35
- data/Gemfile.lock +0 -44
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/HISTORY.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
## 2.0.0 (
|
1
|
+
## 2.0.0.g (2012-01-24)
|
2
|
+
|
3
|
+
* Fixed "already initialized constant" warning (skddc)
|
4
|
+
|
5
|
+
## 2.0.0.f (2011-11-03)
|
2
6
|
|
3
7
|
* TODO: address race condition with delayed jobs (using redis transactions)
|
8
|
+
* Support ENV['BACKGROUND'] flag for daemonizing (bernerdschaefer)
|
9
|
+
* Added support for before_schedule and after_schedule hooks (yaauie)
|
10
|
+
* Added remove_delayed_job_from_timestamp to remove delayed jobs from
|
11
|
+
a given timestamp.
|
4
12
|
|
5
13
|
## 2.0.0.e (2011-09-16)
|
6
14
|
|
data/README.markdown
CHANGED
@@ -55,6 +55,14 @@ to know.
|
|
55
55
|
|
56
56
|
# you probably already have this somewhere
|
57
57
|
Resque.redis = 'localhost:6379'
|
58
|
+
|
59
|
+
# If you want to be able to dynamically change the schedule,
|
60
|
+
# uncomment this line. A dynamic schedule can be updated via the
|
61
|
+
# Resque::Scheduler.set_schedule (and remove_schedule) methods.
|
62
|
+
# When dynamic is set to true, the scheduler process looks for
|
63
|
+
# schedule changes and applies them on the fly.
|
64
|
+
# Note: This feature is only available in >=2.0.0.
|
65
|
+
#Resque::Scheduler.dynamic = true
|
58
66
|
|
59
67
|
# The schedule doesn't need to be stored in a YAML, it just needs to
|
60
68
|
# be a hash. YAML is usually the easiest.
|
@@ -65,15 +73,7 @@ to know.
|
|
65
73
|
# less code that resque-scheduler needs to know about. But in a small
|
66
74
|
# project, it's usually easier to just include you job classes here.
|
67
75
|
# So, someting like this:
|
68
|
-
require 'jobs'
|
69
|
-
|
70
|
-
# If you want to be able to dynamically change the schedule,
|
71
|
-
# uncomment this line. A dynamic schedule can be updated via the
|
72
|
-
# Resque::Scheduler.set_schedule (and remove_schedule) methods.
|
73
|
-
# When dynamic is set to true, the scheduler process looks for
|
74
|
-
# schedule changes and applies them on the fly.
|
75
|
-
# Note: This feature is only available in >=2.0.0.
|
76
|
-
#Resque::Scheduler.dynamic = true
|
76
|
+
require 'jobs'
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -91,7 +91,7 @@ supersedes `VERBOSE`.
|
|
91
91
|
|
92
92
|
NOTE: You DO NOT want to run >1 instance of the scheduler. Doing so will
|
93
93
|
result in the same job being queued more than once. You only need one
|
94
|
-
|
94
|
+
instance of the scheduler running per resque instance (regardless of number
|
95
95
|
of machines).
|
96
96
|
|
97
97
|
If the scheduler process goes down for whatever reason, the delayed items
|
@@ -128,12 +128,18 @@ down when a particular job is supposed to be queue, they will simply "catch up"
|
|
128
128
|
once they are started again. Jobs are guaranteed to run (provided they make it
|
129
129
|
into the delayed queue) after their given queue_at time has passed.
|
130
130
|
|
131
|
+
Similar to `before_enqueue` and `after_enqueue` hooks provided in Resque
|
132
|
+
(>= 1.19.1), your jobs can specify one or more `before_schedule` and
|
133
|
+
`after_schedule` hooks, to be run before or after scheduling. If *any* of your
|
134
|
+
`before_schedule` hooks returns `false`, the job will *not* be scheduled and
|
135
|
+
your `after_schedule` hooks will *not* be run.
|
136
|
+
|
131
137
|
One other thing to note is that insertion into the delayed queue is O(log(n))
|
132
138
|
since the jobs are stored in a redis sorted set (zset). I can't imagine this
|
133
139
|
being an issue for someone since redis is stupidly fast even at log(n), but full
|
134
140
|
disclosure is always best.
|
135
141
|
|
136
|
-
|
142
|
+
#### Removing Delayed jobs
|
137
143
|
|
138
144
|
If you have the need to cancel a delayed job, you can do like so:
|
139
145
|
|
@@ -183,7 +189,25 @@ A big shout out to [rufus-scheduler](http://github.com/jmettraux/rufus-scheduler
|
|
183
189
|
for handling the heavy lifting of the actual scheduling engine.
|
184
190
|
|
185
191
|
|
186
|
-
|
192
|
+
#### Time zones
|
193
|
+
|
194
|
+
Note that if you use the cron syntax, this will be interpreted as in the server time zone
|
195
|
+
rather than the `config.time_zone` specified in Rails.
|
196
|
+
|
197
|
+
You can explicitly specify the time zone that rufus-scheduler will use:
|
198
|
+
|
199
|
+
cron: "30 6 * * 1 Europe/Stockholm"
|
200
|
+
|
201
|
+
Also note that `config.time_zone` in Rails allows for a shorthand (e.g. "Stockholm")
|
202
|
+
that rufus-scheduler does not accept. If you write code to set the scheduler time zone
|
203
|
+
from the `config.time_zone` value, make sure it's the right format, e.g. with:
|
204
|
+
|
205
|
+
ActiveSupport::TimeZone.find_tzinfo(Rails.configuration.time_zone).name
|
206
|
+
|
207
|
+
A future version of resque-scheduler may do this for you.
|
208
|
+
|
209
|
+
|
210
|
+
#### Support for resque-status (and other custom jobs)
|
187
211
|
|
188
212
|
Some Resque extensions like
|
189
213
|
[resque-status](http://github.com/quirkey/resque-status) use custom job
|
@@ -194,11 +218,11 @@ support scheduled job.
|
|
194
218
|
|
195
219
|
Let's pretend we have a JobWithStatus class called FakeLeaderboard
|
196
220
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
221
|
+
class FakeLeaderboard < Resque::JobWithStatus
|
222
|
+
def perform
|
223
|
+
# do something and keep track of the status
|
224
|
+
end
|
225
|
+
end
|
202
226
|
|
203
227
|
And then a schedule:
|
204
228
|
|
@@ -265,6 +289,16 @@ Now make sure you're passing that file to resque-web like so:
|
|
265
289
|
|
266
290
|
That should make the scheduler tabs show up in `resque-web`.
|
267
291
|
|
292
|
+
### Running in the background
|
293
|
+
|
294
|
+
(Only supported with ruby >= 1.9). There are scenarios where it's helpful for
|
295
|
+
the resque worker to run itself in the background (usually in combination with
|
296
|
+
PIDFILE). Use the BACKGROUND option so that rake will return as soon as the
|
297
|
+
worker is started.
|
298
|
+
|
299
|
+
$ PIDFILE=./resque-scheduler.pid BACKGROUND=yes \
|
300
|
+
rake resque:scheduler
|
301
|
+
|
268
302
|
### Plagiarism alert
|
269
303
|
|
270
304
|
This was intended to be an extension to resque and so resulted in a lot of the
|
@@ -278,6 +312,3 @@ work on resque-scheduler.
|
|
278
312
|
For bugs or suggestions, please just open an issue in github.
|
279
313
|
|
280
314
|
Patches are always welcome.
|
281
|
-
|
282
|
-
|
283
|
-
|
data/Rakefile
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'bundler'
|
2
|
-
|
2
|
+
|
3
3
|
Bundler::GemHelper.install_tasks
|
4
4
|
|
5
5
|
$LOAD_PATH.unshift 'lib'
|
6
6
|
|
7
7
|
task :default => :test
|
8
8
|
|
9
|
+
# Tests
|
9
10
|
desc "Run tests"
|
10
11
|
task :test do
|
11
12
|
Dir['test/*_test.rb'].each do |f|
|
@@ -13,9 +14,15 @@ task :test do
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
# Documentation Tasks
|
18
|
+
begin
|
19
|
+
require 'rdoc/task'
|
20
|
+
|
21
|
+
Rake::RDocTask.new do |rd|
|
22
|
+
rd.main = "README.markdown"
|
23
|
+
rd.rdoc_files.include("README.markdown", "lib/**/*.rb")
|
24
|
+
rd.rdoc_dir = 'doc'
|
25
|
+
end
|
26
|
+
rescue LoadError
|
20
27
|
end
|
21
28
|
|
data/lib/resque/scheduler.rb
CHANGED
@@ -116,13 +116,9 @@ module Resque
|
|
116
116
|
interval_types = %w{cron every}
|
117
117
|
interval_types.each do |interval_type|
|
118
118
|
if !config[interval_type].nil? && config[interval_type].length > 0
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
enqueue_from_config(config)
|
123
|
-
end
|
124
|
-
rescue Exception => e
|
125
|
-
log! "#{e.class.name}: #{e.message}"
|
119
|
+
@@scheduled_jobs[name] = rufus_scheduler.send(interval_type, config[interval_type]) do
|
120
|
+
log! "queueing #{config['class']} (#{name})"
|
121
|
+
handle_errors { enqueue_from_config(config) }
|
126
122
|
end
|
127
123
|
interval_defined = true
|
128
124
|
break
|
@@ -160,7 +156,7 @@ module Resque
|
|
160
156
|
handle_shutdown do
|
161
157
|
if item = Resque.next_item_for_timestamp(timestamp)
|
162
158
|
log "queuing #{item['class']} [delayed]"
|
163
|
-
enqueue_from_config(item)
|
159
|
+
handle_errors { enqueue_from_config(item) }
|
164
160
|
end
|
165
161
|
end
|
166
162
|
# continue processing until there are no more ready items in this timestamp
|
@@ -172,6 +168,14 @@ module Resque
|
|
172
168
|
yield
|
173
169
|
exit if @shutdown
|
174
170
|
end
|
171
|
+
|
172
|
+
def handle_errors
|
173
|
+
begin
|
174
|
+
yield
|
175
|
+
rescue Exception => e
|
176
|
+
log! "#{e.class.name}: #{e.message}"
|
177
|
+
end
|
178
|
+
end
|
175
179
|
|
176
180
|
# Enqueues a job based on a config hash
|
177
181
|
def enqueue_from_config(job_config)
|
@@ -200,11 +204,11 @@ module Resque
|
|
200
204
|
if Class === klass
|
201
205
|
Resque.enqueue(klass, *params)
|
202
206
|
else
|
207
|
+
# This will not run the before_hooks in rescue, but will at least
|
208
|
+
# queue the job.
|
203
209
|
Resque::Job.create(queue, klass, *params)
|
204
210
|
end
|
205
211
|
end
|
206
|
-
rescue
|
207
|
-
log! "Failed to enqueue #{klass_name}:\n #{$!}"
|
208
212
|
end
|
209
213
|
|
210
214
|
def rufus_scheduler
|
@@ -275,7 +279,7 @@ module Resque
|
|
275
279
|
|
276
280
|
def procline(string)
|
277
281
|
log! string
|
278
|
-
$0 = "resque-scheduler-#{ResqueScheduler::
|
282
|
+
$0 = "resque-scheduler-#{ResqueScheduler::VERSION}: #{string}"
|
279
283
|
end
|
280
284
|
|
281
285
|
end
|
data/lib/resque_scheduler.rb
CHANGED
@@ -102,14 +102,23 @@ module ResqueScheduler
|
|
102
102
|
# sit in the schedule list.
|
103
103
|
def enqueue_at(timestamp, klass, *args)
|
104
104
|
validate_job!(klass)
|
105
|
-
|
105
|
+
enqueue_at_with_queue( queue_from_class(klass), timestamp, klass, *args)
|
106
106
|
end
|
107
107
|
|
108
108
|
# Identical to +enqueue_at+, except you can also specify
|
109
109
|
# a queue in which the job will be placed after the
|
110
110
|
# timestamp has passed.
|
111
111
|
def enqueue_at_with_queue(queue, timestamp, klass, *args)
|
112
|
+
before_hooks = before_schedule_hooks(klass).collect do |hook|
|
113
|
+
klass.send(hook,*args)
|
114
|
+
end
|
115
|
+
return false if before_hooks.any? { |result| result == false }
|
116
|
+
|
112
117
|
delayed_push(timestamp, job_to_hash_with_queue(queue, klass, args))
|
118
|
+
|
119
|
+
after_schedule_hooks(klass).collect do |hook|
|
120
|
+
klass.send(hook,*args)
|
121
|
+
end
|
113
122
|
end
|
114
123
|
|
115
124
|
# Identical to enqueue_at but takes number_of_seconds_from_now
|
@@ -194,7 +203,10 @@ module ResqueScheduler
|
|
194
203
|
redis.del :delayed_queue_schedule
|
195
204
|
end
|
196
205
|
|
197
|
-
#
|
206
|
+
# Given an encoded item, remove it from the delayed_queue
|
207
|
+
#
|
208
|
+
# This method is potentially very expensive since it needs to scan
|
209
|
+
# through the delayed queue for every timestamp.
|
198
210
|
def remove_delayed(klass, *args)
|
199
211
|
destroyed = 0
|
200
212
|
search = encode(job_to_hash(klass, args))
|
@@ -203,9 +215,21 @@ module ResqueScheduler
|
|
203
215
|
end
|
204
216
|
destroyed
|
205
217
|
end
|
218
|
+
|
219
|
+
# Given a timestamp and job (klass + args) it removes all instances and
|
220
|
+
# returns the count of jobs removed.
|
221
|
+
#
|
222
|
+
# O(N) where N is the number of jobs scheduled to fire at the given
|
223
|
+
# timestamp
|
224
|
+
def remove_delayed_job_from_timestamp(timestamp, klass, *args)
|
225
|
+
key = "delayed:#{timestamp.to_i}"
|
226
|
+
count = redis.lrem key, 0, encode(job_to_hash(klass, args))
|
227
|
+
clean_up_timestamp(key, timestamp)
|
228
|
+
count
|
229
|
+
end
|
206
230
|
|
207
231
|
def count_all_scheduled_jobs
|
208
|
-
total_jobs = 0
|
232
|
+
total_jobs = 0
|
209
233
|
Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |timestamp|
|
210
234
|
total_jobs += redis.llen("delayed:#{timestamp}").to_i
|
211
235
|
end
|
@@ -240,6 +264,14 @@ module ResqueScheduler
|
|
240
264
|
end
|
241
265
|
end
|
242
266
|
|
267
|
+
def before_schedule_hooks(klass)
|
268
|
+
klass.methods.grep(/^before_schedule/).sort
|
269
|
+
end
|
270
|
+
|
271
|
+
def after_schedule_hooks(klass)
|
272
|
+
klass.methods.grep(/^after_schedule/).sort
|
273
|
+
end
|
274
|
+
|
243
275
|
end
|
244
276
|
|
245
277
|
Resque.extend ResqueScheduler
|
@@ -9,6 +9,13 @@ namespace :resque do
|
|
9
9
|
require 'resque'
|
10
10
|
require 'resque_scheduler'
|
11
11
|
|
12
|
+
if ENV['BACKGROUND']
|
13
|
+
unless Process.respond_to?('daemon')
|
14
|
+
abort "env var BACKGROUND is set, which requires ruby >= 1.9"
|
15
|
+
end
|
16
|
+
Process.daemon(true)
|
17
|
+
end
|
18
|
+
|
12
19
|
File.open(ENV['PIDFILE'], 'w') { |f| f << Process.pid.to_s } if ENV['PIDFILE']
|
13
20
|
|
14
21
|
Resque::Scheduler.dynamic = true if ENV['DYNAMIC_SCHEDULE']
|
data/resque-scheduler.gemspec
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
require "resque_scheduler/version"
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
5
6
|
s.name = "resque-scheduler"
|
6
|
-
s.version = ResqueScheduler::
|
7
|
+
s.version = ResqueScheduler::VERSION
|
7
8
|
s.platform = Gem::Platform::RUBY
|
8
9
|
s.authors = ['Ben VandenBos']
|
9
10
|
s.email = ['bvandenbos@gmail.com']
|
@@ -21,8 +22,6 @@ Gem::Specification.new do |s|
|
|
21
22
|
s.require_path = 'lib'
|
22
23
|
|
23
24
|
s.add_runtime_dependency(%q<redis>, [">= 2.0.1"])
|
24
|
-
s.add_runtime_dependency(%q<resque>, [">= 1.
|
25
|
+
s.add_runtime_dependency(%q<resque>, [">= 1.19.0"])
|
25
26
|
s.add_runtime_dependency(%q<rufus-scheduler>, [">= 0"])
|
26
|
-
s.add_development_dependency(%q<mocha>, [">= 0"])
|
27
|
-
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
28
27
|
end
|
data/test/delayed_queue_test.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
|
3
|
+
context "DelayedQueue" do
|
4
4
|
|
5
|
-
|
5
|
+
setup do
|
6
6
|
Resque::Scheduler.mute = true
|
7
7
|
Resque.redis.flushall
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
test "enqueue_at adds correct list and zset" do
|
12
11
|
timestamp = Time.now - 1 # 1 second ago (in the past, should come out right away)
|
13
12
|
|
14
13
|
assert_equal(0, Resque.redis.llen("delayed:#{timestamp.to_i}").to_i, "delayed queue should be empty to start")
|
@@ -34,8 +33,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
34
33
|
assert_equal(0, Resque.redis.zcard(:delayed_queue_schedule), "delayed queue should be empty")
|
35
34
|
end
|
36
35
|
|
37
|
-
|
38
|
-
|
36
|
+
test "enqueue_at with queue adds correct list and zset and queue" do
|
39
37
|
timestamp = Time.now - 1 # 1 second ago (in the past, should come out right away)
|
40
38
|
|
41
39
|
assert_equal(0, Resque.redis.llen("delayed:#{timestamp.to_i}").to_i, "delayed queue should be empty to start")
|
@@ -62,7 +60,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
62
60
|
assert_equal(0, Resque.redis.zcard(:delayed_queue_schedule), "delayed queue should be empty")
|
63
61
|
end
|
64
62
|
|
65
|
-
|
63
|
+
test "a job in the future doesn't come out" do
|
66
64
|
timestamp = Time.now + 600 # 10 minutes from now (in the future, shouldn't come out)
|
67
65
|
|
68
66
|
assert_equal(0, Resque.redis.llen("delayed:#{timestamp.to_i}").to_i, "delayed queue should be empty to start")
|
@@ -78,7 +76,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
78
76
|
assert_nil(read_timestamp, "No timestamps should be ready for queueing")
|
79
77
|
end
|
80
78
|
|
81
|
-
|
79
|
+
test "a job in the future comes out if you want it to" do
|
82
80
|
timestamp = Time.now + 600 # 10 minutes from now
|
83
81
|
|
84
82
|
Resque.enqueue_at(timestamp, SomeIvarJob, "path")
|
@@ -88,7 +86,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
88
86
|
assert_equal(timestamp.to_i, read_timestamp, "The timestamp we pull out of redis should match the one we put in")
|
89
87
|
end
|
90
88
|
|
91
|
-
|
89
|
+
test "enqueue_at and enqueue_in are equivelent" do
|
92
90
|
timestamp = Time.now + 60
|
93
91
|
|
94
92
|
Resque.enqueue_at(timestamp, SomeIvarJob, "path")
|
@@ -98,11 +96,11 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
98
96
|
assert_equal(2, Resque.redis.llen("delayed:#{timestamp.to_i}"), "should have 2 items in the timestamp queue")
|
99
97
|
end
|
100
98
|
|
101
|
-
|
99
|
+
test "empty delayed_queue_peek returns empty array" do
|
102
100
|
assert_equal([], Resque.delayed_queue_peek(0,20))
|
103
101
|
end
|
104
102
|
|
105
|
-
|
103
|
+
test "delqyed_queue_peek returns stuff" do
|
106
104
|
t = Time.now
|
107
105
|
expected_timestamps = (1..5).to_a.map do |i|
|
108
106
|
(t + 60 + i).to_i
|
@@ -117,38 +115,56 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
117
115
|
assert_equal(expected_timestamps[2,3], timestamps)
|
118
116
|
end
|
119
117
|
|
120
|
-
|
118
|
+
test "delayed_queue_schedule_size returns correct size" do
|
121
119
|
assert_equal(0, Resque.delayed_queue_schedule_size)
|
122
120
|
Resque.enqueue_at(Time.now+60, SomeIvarJob)
|
123
121
|
assert_equal(1, Resque.delayed_queue_schedule_size)
|
124
122
|
end
|
125
123
|
|
126
|
-
|
124
|
+
test "delayed_timestamp_size returns 0 when nothing is queue" do
|
125
|
+
t = Time.now + 60
|
126
|
+
assert_equal(0, Resque.delayed_timestamp_size(t))
|
127
|
+
end
|
128
|
+
|
129
|
+
test "delayed_timestamp_size returns 1 when one thing is queued" do
|
127
130
|
t = Time.now + 60
|
128
|
-
assert_equal(0, Resque.delayed_timestamp_size(t))
|
129
131
|
Resque.enqueue_at(t, SomeIvarJob)
|
130
|
-
assert_equal(1, Resque.delayed_timestamp_size(t))
|
131
|
-
assert_equal(0, Resque.delayed_timestamp_size(t.to_i+1))
|
132
|
+
assert_equal(1, Resque.delayed_timestamp_size(t))
|
132
133
|
end
|
133
134
|
|
134
|
-
|
135
|
+
test "delayed_timestamp_peek returns empty array when nothings in it" do
|
135
136
|
t = Time.now + 60
|
136
137
|
assert_equal([], Resque.delayed_timestamp_peek(t, 0, 1), "make sure it's an empty array, not nil")
|
138
|
+
end
|
139
|
+
|
140
|
+
test "delayed_timestamp_peek returns an array containing one job when one thing is queued" do
|
141
|
+
t = Time.now + 60
|
137
142
|
Resque.enqueue_at(t, SomeIvarJob)
|
138
|
-
assert_equal
|
143
|
+
assert_equal [{'args' => [], 'class' => 'SomeIvarJob', 'queue' => 'ivar'}], Resque.delayed_timestamp_peek(t, 0, 1)
|
144
|
+
end
|
145
|
+
|
146
|
+
test "delayed_timestamp_peek returns an array of multiple jobs when more than one job is queued" do
|
147
|
+
t = Time.now + 60
|
139
148
|
Resque.enqueue_at(t, SomeIvarJob)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
149
|
+
Resque.enqueue_at(t, SomeIvarJob)
|
150
|
+
job = {'args' => [], 'class' => 'SomeIvarJob', 'queue' => 'ivar'}
|
151
|
+
assert_equal([job, job], Resque.delayed_timestamp_peek(t, 0, 2))
|
152
|
+
end
|
153
|
+
|
154
|
+
test "delayed_timestamp_peek only returns an array of one job if only asked for 1" do
|
155
|
+
t = Time.now + 60
|
156
|
+
Resque.enqueue_at(t, SomeIvarJob)
|
157
|
+
Resque.enqueue_at(t, SomeIvarJob)
|
158
|
+
job = {'args' => [], 'class' => 'SomeIvarJob', 'queue' => 'ivar'}
|
159
|
+
assert_equal([job], Resque.delayed_timestamp_peek(t, 0, 1))
|
144
160
|
end
|
145
161
|
|
146
|
-
|
162
|
+
test "handle_delayed_items with no items" do
|
147
163
|
Resque::Scheduler.expects(:enqueue).never
|
148
164
|
Resque::Scheduler.handle_delayed_items
|
149
165
|
end
|
150
166
|
|
151
|
-
|
167
|
+
test "handle_delayed_item with items" do
|
152
168
|
t = Time.now - 60 # in the past
|
153
169
|
Resque.enqueue_at(t, SomeIvarJob)
|
154
170
|
Resque.enqueue_at(t, SomeIvarJob)
|
@@ -158,7 +174,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
158
174
|
Resque::Scheduler.handle_delayed_items
|
159
175
|
end
|
160
176
|
|
161
|
-
|
177
|
+
test "handle_delayed_items with items in the future" do
|
162
178
|
t = Time.now + 60 # in the future
|
163
179
|
Resque.enqueue_at(t, SomeIvarJob)
|
164
180
|
Resque.enqueue_at(t, SomeIvarJob)
|
@@ -168,7 +184,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
168
184
|
Resque::Scheduler.handle_delayed_items(t)
|
169
185
|
end
|
170
186
|
|
171
|
-
|
187
|
+
test "enqueue_delayed_items_for_timestamp creates jobs and empties the delayed queue" do
|
172
188
|
t = Time.now + 60
|
173
189
|
|
174
190
|
Resque.enqueue_at(t, SomeIvarJob)
|
@@ -183,7 +199,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
183
199
|
assert_equal(0, Resque.delayed_timestamp_peek(t, 0, 3).length)
|
184
200
|
end
|
185
201
|
|
186
|
-
|
202
|
+
test "handle_delayed_items works with out specifying queue (upgrade case)" do
|
187
203
|
t = Time.now - 60
|
188
204
|
Resque.delayed_push(t, :class => 'SomeIvarJob')
|
189
205
|
|
@@ -195,7 +211,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
195
211
|
Resque::Scheduler.handle_delayed_items
|
196
212
|
end
|
197
213
|
|
198
|
-
|
214
|
+
test "reset_delayed_queue clears the queue" do
|
199
215
|
t = Time.now + 120
|
200
216
|
4.times { Resque.enqueue_at(t, SomeIvarJob) }
|
201
217
|
4.times { Resque.enqueue_at(Time.now + rand(100), SomeIvarJob) }
|
@@ -204,14 +220,14 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
204
220
|
assert_equal(0, Resque.delayed_queue_schedule_size)
|
205
221
|
end
|
206
222
|
|
207
|
-
|
223
|
+
test "remove_delayed removes job and returns the count" do
|
208
224
|
t = Time.now + 120
|
209
225
|
Resque.enqueue_at(t, SomeIvarJob)
|
210
226
|
|
211
227
|
assert_equal(1, Resque.remove_delayed(SomeIvarJob))
|
212
228
|
end
|
213
229
|
|
214
|
-
|
230
|
+
test "remove_delayed doesn't remove things it shouldn't" do
|
215
231
|
t = Time.now + 120
|
216
232
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
217
233
|
Resque.enqueue_at(t, SomeIvarJob, "bar")
|
@@ -221,7 +237,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
221
237
|
assert_equal(0, Resque.remove_delayed(SomeIvarJob))
|
222
238
|
end
|
223
239
|
|
224
|
-
|
240
|
+
test "remove_delayed respected param" do
|
225
241
|
t = Time.now + 120
|
226
242
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
227
243
|
Resque.enqueue_at(t, SomeIvarJob, "bar")
|
@@ -232,7 +248,7 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
232
248
|
assert_equal(1, Resque.delayed_queue_schedule_size)
|
233
249
|
end
|
234
250
|
|
235
|
-
|
251
|
+
test "remove_delayed removes items in different timestamps" do
|
236
252
|
t = Time.now + 120
|
237
253
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
238
254
|
Resque.enqueue_at(t + 1, SomeIvarJob, "bar")
|
@@ -242,8 +258,52 @@ class Resque::DelayedQueueTest < Test::Unit::TestCase
|
|
242
258
|
assert_equal(2, Resque.remove_delayed(SomeIvarJob, "bar"))
|
243
259
|
assert_equal(2, Resque.count_all_scheduled_jobs)
|
244
260
|
end
|
261
|
+
|
262
|
+
test "remove_delayed_job_from_timestamp removes instances of jobs at a given timestamp" do
|
263
|
+
t = Time.now + 120
|
264
|
+
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
265
|
+
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
266
|
+
assert_equal 0, Resque.delayed_timestamp_size(t)
|
267
|
+
end
|
268
|
+
|
269
|
+
test "remove_delayed_job_from_timestamp doesn't remove items from other timestamps" do
|
270
|
+
t1 = Time.now + 120
|
271
|
+
t2 = t1 + 1
|
272
|
+
Resque.enqueue_at(t1, SomeIvarJob, "foo")
|
273
|
+
Resque.enqueue_at(t2, SomeIvarJob, "foo")
|
274
|
+
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t2, SomeIvarJob, "foo")
|
275
|
+
assert_equal 1, Resque.delayed_timestamp_size(t1)
|
276
|
+
assert_equal 0, Resque.delayed_timestamp_size(t2)
|
277
|
+
end
|
278
|
+
|
279
|
+
test "remove_delayed_job_from_timestamp removes nothing if there are no matches" do
|
280
|
+
t = Time.now + 120
|
281
|
+
assert_equal 0, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
282
|
+
end
|
283
|
+
|
284
|
+
test "remove_delayed_job_from_timestamp only removes items that match args" do
|
285
|
+
t = Time.now + 120
|
286
|
+
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
287
|
+
Resque.enqueue_at(t, SomeIvarJob, "bar")
|
288
|
+
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
289
|
+
assert_equal 1, Resque.delayed_timestamp_size(t)
|
290
|
+
end
|
291
|
+
|
292
|
+
test "remove_delayed_job_from_timestamp returns the number of items removed" do
|
293
|
+
t = Time.now + 120
|
294
|
+
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
295
|
+
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
296
|
+
end
|
297
|
+
|
298
|
+
test "remove_delayed_job_from_timestamp should cleanup the delayed timestamp list if not jobs are left" do
|
299
|
+
t = Time.now + 120
|
300
|
+
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
301
|
+
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
302
|
+
assert !Resque.redis.exists("delayed:#{t.to_i}")
|
303
|
+
assert Resque.delayed_queue_peek(0, 100).empty?
|
304
|
+
end
|
245
305
|
|
246
|
-
|
306
|
+
test "invalid job class" do
|
247
307
|
assert_raise Resque::NoClassError do
|
248
308
|
Resque.enqueue_in(10, nil)
|
249
309
|
end
|
data/test/scheduler_args_test.rb
CHANGED
@@ -1,7 +1,70 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
context "scheduling jobs with arguments" do
|
4
|
-
|
4
|
+
|
5
|
+
setup do
|
6
|
+
Resque::Scheduler.clear_schedule!
|
7
|
+
Resque::Scheduler.dynamic = false
|
8
|
+
Resque::Scheduler.mute = true
|
9
|
+
end
|
10
|
+
|
11
|
+
test "enqueue_from_config puts stuff in resque without class loaded" do
|
12
|
+
Resque::Job.stubs(:create).once.returns(true).with('joes_queue', 'UndefinedJob', '/tmp')
|
13
|
+
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'UndefinedJob', 'args' => "/tmp", 'queue' => 'joes_queue')
|
14
|
+
end
|
15
|
+
|
16
|
+
test "enqueue_from_config with_every_syntax" do
|
17
|
+
Resque::Job.stubs(:create).once.returns(true).with('james_queue', 'JamesJob', '/tmp')
|
18
|
+
Resque::Scheduler.enqueue_from_config('every' => '1m', 'class' => 'JamesJob', 'args' => '/tmp', 'queue' => 'james_queue')
|
19
|
+
end
|
20
|
+
|
21
|
+
test "enqueue_from_config puts jobs in the resque queue" do
|
22
|
+
Resque::Job.stubs(:create).once.returns(true).with(:ivar, SomeIvarJob, '/tmp')
|
23
|
+
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
|
24
|
+
end
|
25
|
+
|
26
|
+
test "enqueue_from_config with custom_class_job in resque" do
|
27
|
+
FakeCustomJobClass.stubs(:scheduled).once.returns(true).with(:ivar, 'SomeIvarJob', '/tmp')
|
28
|
+
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'custom_job_class' => 'FakeCustomJobClass', 'args' => "/tmp")
|
29
|
+
end
|
30
|
+
|
31
|
+
test "enqueue_from_config puts stuff in resquewhen rails_env matches" do
|
32
|
+
# The job should be loaded : its rails_env config matches the RAILS_ENV variable:
|
33
|
+
ENV['RAILS_ENV'] = 'production'
|
34
|
+
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
35
|
+
|
36
|
+
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'production'}}
|
37
|
+
Resque::Scheduler.load_schedule!
|
38
|
+
assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
39
|
+
|
40
|
+
# we allow multiple rails_env definition, it should work also:
|
41
|
+
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging, production'}}
|
42
|
+
Resque::Scheduler.load_schedule!
|
43
|
+
assert_equal(2, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "enqueue_from_config doesnt put stuff in resque when rails_env doesnt match" do
|
47
|
+
# RAILS_ENV is not set:
|
48
|
+
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
49
|
+
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
|
50
|
+
Resque::Scheduler.load_schedule!
|
51
|
+
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
52
|
+
|
53
|
+
# SET RAILS_ENV to a common value:
|
54
|
+
ENV['RAILS_ENV'] = 'production'
|
55
|
+
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
|
56
|
+
Resque::Scheduler.load_schedule!
|
57
|
+
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "enqueue_from_config when rails env arg is not set" do
|
61
|
+
# The job should be loaded, since a missing rails_env means ALL envs.
|
62
|
+
ENV['RAILS_ENV'] = 'production'
|
63
|
+
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
64
|
+
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
|
65
|
+
Resque::Scheduler.load_schedule!
|
66
|
+
assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
67
|
+
end
|
5
68
|
|
6
69
|
test "calls the worker without arguments when 'args' is missing from the config" do
|
7
70
|
Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
context "scheduling jobs with hooks" do
|
4
|
+
class JobThatCannotBeScheduledWithoutArguments < Resque::Job
|
5
|
+
@queue = :job_that_cannot_be_scheduled_without_arguments
|
6
|
+
def self.perform(*x);end
|
7
|
+
def self.before_schedule_return_nil_if_arguments_not_supplied(*args)
|
8
|
+
counters[:before_schedule] += 1
|
9
|
+
return false if args.empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.after_schedule_do_something(*args)
|
13
|
+
counters[:after_schedule] += 1
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def counters
|
18
|
+
@counters ||= Hash.new{|h,k| h[k]=0}
|
19
|
+
end
|
20
|
+
def clean
|
21
|
+
counters.clear
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
setup do
|
28
|
+
Resque::Scheduler.dynamic = false
|
29
|
+
Resque.redis.del(:schedules)
|
30
|
+
Resque.redis.del(:schedules_changed)
|
31
|
+
Resque::Scheduler.mute = true
|
32
|
+
Resque::Scheduler.clear_schedule!
|
33
|
+
Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
|
34
|
+
end
|
35
|
+
|
36
|
+
test "before_schedule hook that does not return false should not block" do
|
37
|
+
enqueue_time = Time.now + 12
|
38
|
+
Resque.enqueue_at(enqueue_time, JobThatCannotBeScheduledWithoutArguments.clean, :foo)
|
39
|
+
assert_equal(1, Resque.delayed_timestamp_size(enqueue_time.to_i), "delayed queue should have one entry now")
|
40
|
+
assert_equal(1, JobThatCannotBeScheduledWithoutArguments.counters[:before_schedule], 'before_schedule was not run')
|
41
|
+
assert_equal(1, JobThatCannotBeScheduledWithoutArguments.counters[:after_schedule], 'after_schedule was not run')
|
42
|
+
end
|
43
|
+
|
44
|
+
test "before_schedule hook that returns false should block" do
|
45
|
+
enqueue_time = Time.now + 60
|
46
|
+
assert_equal(0, JobThatCannotBeScheduledWithoutArguments.clean.counters[:before_schedule], 'before_schedule should be zero')
|
47
|
+
Resque.enqueue_at(enqueue_time, JobThatCannotBeScheduledWithoutArguments.clean)
|
48
|
+
assert_equal(0, Resque.delayed_timestamp_size(enqueue_time.to_i), "job should not have been put in queue")
|
49
|
+
assert_equal(1, JobThatCannotBeScheduledWithoutArguments.counters[:before_schedule], 'before_schedule was not run')
|
50
|
+
assert_equal(0, JobThatCannotBeScheduledWithoutArguments.counters[:after_schedule], 'after_schedule was run')
|
51
|
+
end
|
52
|
+
end
|
data/test/scheduler_test.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
|
3
|
+
context "Resque::Scheduler" do
|
4
4
|
|
5
|
-
|
6
|
-
def self.scheduled(queue, klass, *args); end
|
7
|
-
end
|
8
|
-
|
9
|
-
def setup
|
5
|
+
setup do
|
10
6
|
Resque::Scheduler.dynamic = false
|
11
7
|
Resque.redis.del(:schedules)
|
12
8
|
Resque.redis.del(:schedules_changed)
|
@@ -15,70 +11,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
15
11
|
Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
|
16
12
|
end
|
17
13
|
|
18
|
-
|
19
|
-
Resque::Job.stubs(:create).once.returns(true).with('joes_queue', 'BigJoesJob', '/tmp')
|
20
|
-
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'BigJoesJob', 'args' => "/tmp", 'queue' => 'joes_queue')
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_enqueue_from_config_with_every_syntax
|
24
|
-
Resque::Job.stubs(:create).once.returns(true).with('james_queue', 'JamesJob', '/tmp')
|
25
|
-
Resque::Scheduler.enqueue_from_config('every' => '1m', 'class' => 'JamesJob', 'args' => '/tmp', 'queue' => 'james_queue')
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_enqueue_from_config_doesnt_crash_on_exception_when_enqueueing
|
29
|
-
Resque::Job.stubs(:create).raises(Resque::NoQueueError, 'test exception').with(:ivar, 'SomeIvarJob', '/tmp')
|
30
|
-
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_enqueue_from_config_puts_stuff_in_the_resque_queue
|
34
|
-
Resque::Job.stubs(:create).once.returns(true).with(:ivar, SomeIvarJob, '/tmp')
|
35
|
-
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_enqueue_from_config_with_custom_class_job_in_the_resque_queue
|
39
|
-
FakeJob.stubs(:scheduled).once.returns(true).with(:ivar, 'SomeIvarJob', '/tmp')
|
40
|
-
Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'custom_job_class' => 'Resque::SchedulerTest::FakeJob', 'args' => "/tmp")
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_enqueue_from_config_puts_stuff_in_the_resque_queue_when_env_match
|
44
|
-
# The job should be loaded : its rails_env config matches the RAILS_ENV variable:
|
45
|
-
ENV['RAILS_ENV'] = 'production'
|
46
|
-
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
47
|
-
|
48
|
-
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'production'}}
|
49
|
-
Resque::Scheduler.load_schedule!
|
50
|
-
assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
51
|
-
|
52
|
-
# we allow multiple rails_env definition, it should work also:
|
53
|
-
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging, production'}}
|
54
|
-
Resque::Scheduler.load_schedule!
|
55
|
-
assert_equal(2, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_enqueue_from_config_dont_puts_stuff_in_the_resque_queue_when_env_doesnt_match
|
59
|
-
# RAILS_ENV is not set:
|
60
|
-
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
61
|
-
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
|
62
|
-
Resque::Scheduler.load_schedule!
|
63
|
-
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
64
|
-
|
65
|
-
# SET RAILS_ENV to a common value:
|
66
|
-
ENV['RAILS_ENV'] = 'production'
|
67
|
-
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
|
68
|
-
Resque::Scheduler.load_schedule!
|
69
|
-
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_enqueue_from_config_when_rails_env_arg_is_not_set
|
73
|
-
# The job should be loaded, since a missing rails_env means ALL envs.
|
74
|
-
ENV['RAILS_ENV'] = 'production'
|
75
|
-
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
76
|
-
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
|
77
|
-
Resque::Scheduler.load_schedule!
|
78
|
-
assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
79
|
-
end
|
80
|
-
|
81
|
-
def test_enqueue_constantizes
|
14
|
+
test "enqueue constantizes" do
|
82
15
|
# The job should be loaded, since a missing rails_env means ALL envs.
|
83
16
|
ENV['RAILS_ENV'] = 'production'
|
84
17
|
config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
|
@@ -86,7 +19,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
86
19
|
Resque::Scheduler.enqueue_from_config(config)
|
87
20
|
end
|
88
21
|
|
89
|
-
|
22
|
+
test "enqueue runs hooks" do
|
90
23
|
# The job should be loaded, since a missing rails_env means ALL envs.
|
91
24
|
ENV['RAILS_ENV'] = 'production'
|
92
25
|
config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
|
@@ -97,7 +30,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
97
30
|
Resque::Scheduler.enqueue_from_config(config)
|
98
31
|
end
|
99
32
|
|
100
|
-
|
33
|
+
test "config makes it into the rufus_scheduler" do
|
101
34
|
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
102
35
|
|
103
36
|
Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
|
@@ -107,7 +40,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
107
40
|
assert Resque::Scheduler.scheduled_jobs.include?(:some_ivar_job)
|
108
41
|
end
|
109
42
|
|
110
|
-
|
43
|
+
test "can reload schedule" do
|
111
44
|
Resque::Scheduler.dynamic = true
|
112
45
|
Resque.schedule = {"some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
|
113
46
|
|
@@ -129,7 +62,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
129
62
|
assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job2")
|
130
63
|
end
|
131
64
|
|
132
|
-
|
65
|
+
test "load_schedule_job loads a schedule" do
|
133
66
|
Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"})
|
134
67
|
|
135
68
|
assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
@@ -137,7 +70,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
137
70
|
assert Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
|
138
71
|
end
|
139
72
|
|
140
|
-
|
73
|
+
test "load_schedule_job without cron" do
|
141
74
|
Resque::Scheduler.load_schedule_job("some_ivar_job", {'class' => 'SomeIvarJob', 'args' => "/tmp"})
|
142
75
|
|
143
76
|
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
@@ -145,7 +78,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
145
78
|
assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
|
146
79
|
end
|
147
80
|
|
148
|
-
|
81
|
+
test "load_schedule_job with an empty cron" do
|
149
82
|
Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => '', 'class' => 'SomeIvarJob', 'args' => "/tmp"})
|
150
83
|
|
151
84
|
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
@@ -153,7 +86,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
153
86
|
assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
|
154
87
|
end
|
155
88
|
|
156
|
-
|
89
|
+
test "update_schedule" do
|
157
90
|
Resque::Scheduler.dynamic = true
|
158
91
|
Resque.schedule = {
|
159
92
|
"some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
|
@@ -187,7 +120,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
187
120
|
assert_equal 0, Resque.redis.scard(:schedules_changed)
|
188
121
|
end
|
189
122
|
|
190
|
-
|
123
|
+
test "update_schedule with mocks" do
|
191
124
|
Resque::Scheduler.dynamic = true
|
192
125
|
Resque.schedule = {
|
193
126
|
"some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
|
@@ -223,7 +156,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
223
156
|
assert_equal 0, Resque.redis.scard(:schedules_changed)
|
224
157
|
end
|
225
158
|
|
226
|
-
|
159
|
+
test "schedule= sets the schedule" do
|
227
160
|
Resque::Scheduler.dynamic = true
|
228
161
|
Resque.schedule = {"my_ivar_job" => {
|
229
162
|
'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"
|
@@ -232,7 +165,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
232
165
|
Resque.decode(Resque.redis.hget(:schedules, "my_ivar_job")))
|
233
166
|
end
|
234
167
|
|
235
|
-
|
168
|
+
test "set_schedule can set an individual schedule" do
|
236
169
|
Resque.set_schedule("some_ivar_job", {
|
237
170
|
'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"
|
238
171
|
})
|
@@ -241,7 +174,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
241
174
|
assert Resque.redis.sismember(:schedules_changed, "some_ivar_job")
|
242
175
|
end
|
243
176
|
|
244
|
-
|
177
|
+
test "get_schedule returns a schedule" do
|
245
178
|
Resque.redis.hset(:schedules, "some_ivar_job2", Resque.encode(
|
246
179
|
{'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/33"}
|
247
180
|
))
|
@@ -249,7 +182,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
249
182
|
Resque.get_schedule("some_ivar_job2"))
|
250
183
|
end
|
251
184
|
|
252
|
-
|
185
|
+
test "remove_schedule removes a schedule" do
|
253
186
|
Resque.redis.hset(:schedules, "some_ivar_job3", Resque.encode(
|
254
187
|
{'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/44"}
|
255
188
|
))
|
@@ -258,7 +191,7 @@ class Resque::SchedulerTest < Test::Unit::TestCase
|
|
258
191
|
assert Resque.redis.sismember(:schedules_changed, "some_ivar_job3")
|
259
192
|
end
|
260
193
|
|
261
|
-
|
194
|
+
test "adheres to lint" do
|
262
195
|
assert_nothing_raised do
|
263
196
|
Resque::Plugin.lint(Resque::Scheduler)
|
264
197
|
Resque::Plugin.lint(ResqueScheduler)
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.g
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-24 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement: &
|
16
|
+
requirement: &2160604100 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.0.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2160604100
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis
|
27
|
-
requirement: &
|
27
|
+
requirement: &2160602220 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,21 +32,21 @@ dependencies:
|
|
32
32
|
version: 2.0.1
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2160602220
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: resque
|
38
|
-
requirement: &
|
38
|
+
requirement: &2160601740 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.
|
43
|
+
version: 1.19.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2160601740
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rufus-scheduler
|
49
|
-
requirement: &
|
49
|
+
requirement: &2160601260 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,29 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: mocha
|
60
|
-
requirement: &2163769160 !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ! '>='
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version: '0'
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *2163769160
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rack-test
|
71
|
-
requirement: &2163768680 !ruby/object:Gem::Requirement
|
72
|
-
none: false
|
73
|
-
requirements:
|
74
|
-
- - ! '>='
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '0'
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: *2163768680
|
57
|
+
version_requirements: *2160601260
|
80
58
|
description: ! "Light weight job scheduling on top of Resque.\n Adds methods enqueue_at/enqueue_in
|
81
59
|
to schedule jobs in the future.\n Also supports queueing jobs on a fixed, cron-like
|
82
60
|
schedule."
|
@@ -88,7 +66,6 @@ extra_rdoc_files: []
|
|
88
66
|
files:
|
89
67
|
- .gitignore
|
90
68
|
- Gemfile
|
91
|
-
- Gemfile.lock
|
92
69
|
- HISTORY.md
|
93
70
|
- LICENSE
|
94
71
|
- README.markdown
|
@@ -107,6 +84,7 @@ files:
|
|
107
84
|
- test/redis-test.conf
|
108
85
|
- test/resque-web_test.rb
|
109
86
|
- test/scheduler_args_test.rb
|
87
|
+
- test/scheduler_hooks_test.rb
|
110
88
|
- test/scheduler_test.rb
|
111
89
|
- test/test_helper.rb
|
112
90
|
homepage: http://github.com/bvandenbos/resque-scheduler
|
@@ -123,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
101
|
version: '0'
|
124
102
|
segments:
|
125
103
|
- 0
|
126
|
-
hash: -
|
104
|
+
hash: -2970363216344829182
|
127
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
106
|
none: false
|
129
107
|
requirements:
|
data/Gemfile.lock
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
resque-scheduler (2.0.0.e)
|
5
|
-
redis (>= 2.0.1)
|
6
|
-
resque (>= 1.15.0)
|
7
|
-
rufus-scheduler
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: http://rubygems.org/
|
11
|
-
specs:
|
12
|
-
json (1.4.6)
|
13
|
-
mocha (0.9.9)
|
14
|
-
rake
|
15
|
-
rack (1.2.1)
|
16
|
-
rack-test (0.5.6)
|
17
|
-
rack (>= 1.0)
|
18
|
-
rake (0.8.7)
|
19
|
-
redis (2.2.2)
|
20
|
-
redis-namespace (1.1.0)
|
21
|
-
redis (< 3.0.0)
|
22
|
-
resque (1.15.0)
|
23
|
-
json (~> 1.4.6)
|
24
|
-
redis-namespace (>= 0.10.0)
|
25
|
-
sinatra (>= 0.9.2)
|
26
|
-
vegas (~> 0.1.2)
|
27
|
-
rufus-scheduler (2.0.10)
|
28
|
-
tzinfo (>= 0.3.23)
|
29
|
-
sinatra (1.2.6)
|
30
|
-
rack (~> 1.1)
|
31
|
-
tilt (>= 1.2.2, < 2.0)
|
32
|
-
tilt (1.3.2)
|
33
|
-
tzinfo (0.3.29)
|
34
|
-
vegas (0.1.8)
|
35
|
-
rack (>= 1.0.0)
|
36
|
-
|
37
|
-
PLATFORMS
|
38
|
-
ruby
|
39
|
-
|
40
|
-
DEPENDENCIES
|
41
|
-
bundler (>= 1.0.0)
|
42
|
-
mocha
|
43
|
-
rack-test
|
44
|
-
resque-scheduler!
|