resque-scheduler 2.0.0.h → 2.0.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.
- data/.gitignore +1 -0
- data/HISTORY.md +14 -8
- data/README.markdown +38 -21
- data/lib/resque/scheduler.rb +7 -8
- data/lib/resque_scheduler.rb +33 -28
- data/lib/resque_scheduler/plugin.rb +1 -1
- data/lib/resque_scheduler/server.rb +11 -5
- data/lib/resque_scheduler/version.rb +1 -1
- data/resque-scheduler.gemspec +1 -1
- data/test/delayed_queue_test.rb +34 -19
- data/test/scheduler_test.rb +8 -0
- data/test/test_helper.rb +2 -2
- metadata +33 -16
data/.gitignore
CHANGED
data/HISTORY.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
## 2.0.0
|
1
|
+
## 2.0.0
|
2
|
+
|
3
|
+
* Add support for Resque.inline configuration (carlosantoniodasilva)
|
4
|
+
* Fixing possible job loss race condition around deleting delayed queues
|
5
|
+
and enqueuing a job 0 seconds in the future.
|
6
|
+
|
7
|
+
### 2.0.0.h (2012-03-19)
|
2
8
|
|
3
9
|
* Adding plugin support with hooks (andreas)
|
4
10
|
|
5
|
-
|
11
|
+
### 2.0.0.f (2011-11-03)
|
6
12
|
|
7
13
|
* TODO: address race condition with delayed jobs (using redis transactions)
|
8
14
|
* Support ENV['BACKGROUND'] flag for daemonizing (bernerdschaefer)
|
@@ -10,7 +16,7 @@
|
|
10
16
|
* Added remove_delayed_job_from_timestamp to remove delayed jobs from
|
11
17
|
a given timestamp.
|
12
18
|
|
13
|
-
|
19
|
+
### 2.0.0.e (2011-09-16)
|
14
20
|
|
15
21
|
* Adding enqueue_at_with_queue/enqueue_in_with_queue support (niralisse)
|
16
22
|
* Adding `Resque::Scheduler.poll_sleep_amount` to allow for configuring
|
@@ -18,19 +24,19 @@
|
|
18
24
|
* Add a "Clear Delayed Jobs" button to the Delayed Jobs page (john-griffin)
|
19
25
|
* Fixed pagination issue on the Delayed tab
|
20
26
|
|
21
|
-
|
27
|
+
### 2.0.0.d (2011-04-04)
|
22
28
|
|
23
29
|
* porting bug fixes from v1.9-stable
|
24
30
|
|
25
|
-
|
31
|
+
### 2.0.0.c
|
26
32
|
|
27
33
|
* Rake task drop a pid file (sreeix)
|
28
34
|
|
29
|
-
|
35
|
+
### 2.0.0.b
|
30
36
|
|
31
37
|
* Bug fixes
|
32
38
|
|
33
|
-
|
39
|
+
### 2.0.0.a
|
34
40
|
|
35
41
|
* Dynamic schedule support (brianjlandau, davidyang)
|
36
42
|
* Now depends on redis >=1.3
|
@@ -108,7 +114,7 @@
|
|
108
114
|
|
109
115
|
## 1.0.4 (2010-02-26)
|
110
116
|
|
111
|
-
* Added support for specifying the queue to put the job onto. This allows for
|
117
|
+
* Added support for specifying the queue to put the job onto. This allows for
|
112
118
|
you to have one job that can go onto multiple queues and be able to schedule
|
113
119
|
jobs without having to load the job classes.
|
114
120
|
|
data/README.markdown
CHANGED
@@ -6,7 +6,13 @@ resque-scheduler
|
|
6
6
|
Resque-scheduler is an extension to [Resque](http://github.com/defunkt/resque)
|
7
7
|
that adds support for queueing items in the future.
|
8
8
|
|
9
|
-
|
9
|
+
This table explains the version requirements for redis
|
10
|
+
|
11
|
+
| resque-scheduler version | required redis version|
|
12
|
+
|:-------------------------|----------------------:|
|
13
|
+
| >= 2.0.0 | >= 2.2.0 |
|
14
|
+
| >= 0.0.1 | >= 1.3 |
|
15
|
+
|
10
16
|
|
11
17
|
Job scheduling is supported in two different way: Recurring (scheduled) and
|
12
18
|
Delayed.
|
@@ -21,7 +27,7 @@ The syntax is pretty explanatory:
|
|
21
27
|
|
22
28
|
### Documentation
|
23
29
|
|
24
|
-
This README covers what most people need to know. If you're looking for
|
30
|
+
This README covers what most people need to know. If you're looking for
|
25
31
|
details on individual methods, you might want to try the [rdoc](http://rdoc.info/github/bvandenbos/resque-scheduler/master/frames).
|
26
32
|
|
27
33
|
### Installation
|
@@ -30,9 +36,13 @@ To install:
|
|
30
36
|
|
31
37
|
gem install resque-scheduler
|
32
38
|
|
39
|
+
If you use a Gemfile, you may want to specify the `:require` explicitly:
|
40
|
+
|
41
|
+
gem 'resque-scheduler', :require => 'resque_scheduler'
|
42
|
+
|
33
43
|
Adding the resque:scheduler rake task:
|
34
44
|
|
35
|
-
require 'resque_scheduler/tasks'
|
45
|
+
require 'resque_scheduler/tasks'
|
36
46
|
|
37
47
|
There are three things `resque-scheduler` needs to know about in order to do
|
38
48
|
it's jobs: the schedule, where redis lives, and which queues to use. The
|
@@ -45,35 +55,35 @@ to know.
|
|
45
55
|
|
46
56
|
# Resque tasks
|
47
57
|
require 'resque/tasks'
|
48
|
-
require 'resque_scheduler/tasks'
|
49
|
-
|
58
|
+
require 'resque_scheduler/tasks'
|
59
|
+
|
50
60
|
namespace :resque do
|
51
61
|
task :setup do
|
52
62
|
require 'resque'
|
53
63
|
require 'resque_scheduler'
|
54
|
-
require 'resque/scheduler'
|
55
|
-
|
64
|
+
require 'resque/scheduler'
|
65
|
+
|
56
66
|
# you probably already have this somewhere
|
57
67
|
Resque.redis = 'localhost:6379'
|
58
68
|
|
59
69
|
# If you want to be able to dynamically change the schedule,
|
60
70
|
# uncomment this line. A dynamic schedule can be updated via the
|
61
71
|
# Resque::Scheduler.set_schedule (and remove_schedule) methods.
|
62
|
-
# When dynamic is set to true, the scheduler process looks for
|
72
|
+
# When dynamic is set to true, the scheduler process looks for
|
63
73
|
# schedule changes and applies them on the fly.
|
64
74
|
# Note: This feature is only available in >=2.0.0.
|
65
75
|
#Resque::Scheduler.dynamic = true
|
66
|
-
|
76
|
+
|
67
77
|
# The schedule doesn't need to be stored in a YAML, it just needs to
|
68
78
|
# be a hash. YAML is usually the easiest.
|
69
79
|
Resque.schedule = YAML.load_file('your_resque_schedule.yml')
|
70
|
-
|
80
|
+
|
71
81
|
# If your schedule already has +queue+ set for each job, you don't
|
72
82
|
# need to require your jobs. This can be an advantage since it's
|
73
83
|
# less code that resque-scheduler needs to know about. But in a small
|
74
84
|
# project, it's usually easier to just include you job classes here.
|
75
85
|
# So, someting like this:
|
76
|
-
require 'jobs'
|
86
|
+
require 'jobs'
|
77
87
|
end
|
78
88
|
end
|
79
89
|
|
@@ -82,7 +92,7 @@ queueing items from the schedule and polling the delayed queue for items
|
|
82
92
|
ready to be pushed on to the work queues. For obvious reasons, this process
|
83
93
|
never exits.
|
84
94
|
|
85
|
-
$ rake resque:scheduler
|
95
|
+
$ rake resque:scheduler
|
86
96
|
|
87
97
|
Supported environment variables are `VERBOSE` and `MUTE`. If either is set to
|
88
98
|
any nonempty value, they will take effect. `VERBOSE` simply dumps more output
|
@@ -118,7 +128,7 @@ time is in the past, the job moves from the delayed queue to the actual resque
|
|
118
128
|
work queue and will be completed as workers as free to process it.
|
119
129
|
|
120
130
|
Also supported is `Resque.enqueue_at` which takes a timestamp to queue the
|
121
|
-
job, and `Resque.enqueue_at_with_queue` which takes both a timestamp and a
|
131
|
+
job, and `Resque.enqueue_at_with_queue` which takes both a timestamp and a
|
122
132
|
queue name.
|
123
133
|
|
124
134
|
The delayed queue is stored in redis and is persisted in the same way the
|
@@ -163,7 +173,7 @@ is most likely stored in a YAML like so:
|
|
163
173
|
# If you want to have a different job name and class name, provide the 'class' option
|
164
174
|
class: QueueDocuments
|
165
175
|
queue: high
|
166
|
-
args:
|
176
|
+
args:
|
167
177
|
description: "This job queues all content for indexing in solr"
|
168
178
|
|
169
179
|
clear_leaderboards_contributors:
|
@@ -174,7 +184,7 @@ is most likely stored in a YAML like so:
|
|
174
184
|
description: "This job resets the weekly leaderboard for contributions"
|
175
185
|
|
176
186
|
The queue value is optional, but if left unspecified resque-scheduler will
|
177
|
-
attempt to get the queue from the job class, which means it needs to be
|
187
|
+
attempt to get the queue from the job class, which means it needs to be
|
178
188
|
defined. If you're getting "uninitialized constant" errors, you probably
|
179
189
|
need to either set the queue in the schedule or require your jobs in your
|
180
190
|
"resque:setup" rake task.
|
@@ -253,7 +263,7 @@ And then a schedule:
|
|
253
263
|
cron: "30 6 * * 1"
|
254
264
|
queue: scoring
|
255
265
|
custom_job_class: FakeLeaderboard
|
256
|
-
args:
|
266
|
+
args:
|
257
267
|
rails_env: demo
|
258
268
|
description: "This job will auto-create leaderboards for our online demo and the status will update as the worker makes progress"
|
259
269
|
|
@@ -286,10 +296,12 @@ The Delayed tab:
|
|
286
296
|
|
287
297
|

|
288
298
|
|
299
|
+
#### How do I get the schedule tabs to show up???
|
300
|
+
|
289
301
|
To get these to show up you need to pass a file to `resque-web` to tell it to
|
290
|
-
include the `resque-scheduler` plugin
|
291
|
-
|
292
|
-
like this:
|
302
|
+
include the `resque-scheduler` plugin and the resque-schedule server extension
|
303
|
+
to the resque-web sinatra app. Unless you're running redis on localhost, you
|
304
|
+
probably already have this file. It probably looks something like this:
|
293
305
|
|
294
306
|
require 'resque' # include resque so we can configure it
|
295
307
|
Resque.redis = "redis_server:6379" # tell Resque where redis lives
|
@@ -298,8 +310,14 @@ Now, you want to add the following:
|
|
298
310
|
|
299
311
|
# This will make the tabs show up.
|
300
312
|
require 'resque_scheduler'
|
313
|
+
require 'resque_scheduler/server'
|
314
|
+
|
315
|
+
That should make the scheduler tabs show up in `resque-web`.
|
301
316
|
|
302
|
-
|
317
|
+
|
318
|
+
#### Changes as of 2.0.0
|
319
|
+
|
320
|
+
As of resque-scheduler 2.0.0, it's no longer necessary to have the resque-web
|
303
321
|
process aware of the schedule because it reads it from redis. But prior to
|
304
322
|
2.0, you'll want to make sure you load the schedule in this file as well.
|
305
323
|
Something like this:
|
@@ -310,7 +328,6 @@ Now make sure you're passing that file to resque-web like so:
|
|
310
328
|
|
311
329
|
resque-web ~/yourapp/config/resque_config.rb
|
312
330
|
|
313
|
-
That should make the scheduler tabs show up in `resque-web`.
|
314
331
|
|
315
332
|
### Running in the background
|
316
333
|
|
data/lib/resque/scheduler.rb
CHANGED
@@ -17,7 +17,7 @@ module Resque
|
|
17
17
|
|
18
18
|
# If set, will try to update the schulde in the loop
|
19
19
|
attr_accessor :dynamic
|
20
|
-
|
20
|
+
|
21
21
|
# Amount of time in seconds to sleep between polls of the delayed
|
22
22
|
# queue. Defaults to 5
|
23
23
|
attr_writer :poll_sleep_amount
|
@@ -26,7 +26,7 @@ module Resque
|
|
26
26
|
def scheduled_jobs
|
27
27
|
@@scheduled_jobs
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def poll_sleep_amount
|
31
31
|
@poll_sleep_amount ||= 5 # seconds
|
32
32
|
end
|
@@ -75,7 +75,7 @@ module Resque
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def print_schedule
|
78
|
+
def print_schedule
|
79
79
|
if rufus_scheduler
|
80
80
|
log! "Scheduling Info\tLast Run"
|
81
81
|
scheduler_jobs = rufus_scheduler.all_jobs
|
@@ -89,7 +89,7 @@ module Resque
|
|
89
89
|
# rufus scheduler instance
|
90
90
|
def load_schedule!
|
91
91
|
procline "Loading Schedule"
|
92
|
-
|
92
|
+
|
93
93
|
# Need to load the schedule from redis for the first time if dynamic
|
94
94
|
Resque.reload_schedule! if dynamic
|
95
95
|
|
@@ -103,7 +103,7 @@ module Resque
|
|
103
103
|
Resque.redis.del(:schedules_changed)
|
104
104
|
procline "Schedules Loaded"
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
# modify interval type value to value with options if options available
|
108
108
|
def optionizate_interval_value(value)
|
109
109
|
args = value
|
@@ -155,7 +155,6 @@ module Resque
|
|
155
155
|
# Handles queueing delayed items
|
156
156
|
# at_time - Time to start scheduling items (default: now).
|
157
157
|
def handle_delayed_items(at_time=nil)
|
158
|
-
item = nil
|
159
158
|
if timestamp = Resque.next_delayed_timestamp(at_time)
|
160
159
|
procline "Processing Delayed Items"
|
161
160
|
while !timestamp.nil?
|
@@ -184,7 +183,7 @@ module Resque
|
|
184
183
|
yield
|
185
184
|
exit if @shutdown
|
186
185
|
end
|
187
|
-
|
186
|
+
|
188
187
|
def handle_errors
|
189
188
|
begin
|
190
189
|
yield
|
@@ -219,7 +218,7 @@ module Resque
|
|
219
218
|
# one app that schedules for another
|
220
219
|
if Class === klass
|
221
220
|
ResqueScheduler::Plugin.run_before_delayed_enqueue_hooks(klass, *params)
|
222
|
-
Resque.
|
221
|
+
Resque.enqueue_to(queue, klass, *params)
|
223
222
|
else
|
224
223
|
# This will not run the before_hooks in rescue, but will at least
|
225
224
|
# queue the job.
|
data/lib/resque_scheduler.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'resque'
|
3
|
-
require 'resque/server'
|
4
3
|
require 'resque_scheduler/version'
|
5
4
|
require 'resque/scheduler'
|
6
|
-
require 'resque_scheduler/server'
|
7
5
|
require 'resque_scheduler/plugin'
|
8
6
|
|
9
7
|
module ResqueScheduler
|
@@ -59,12 +57,12 @@ module ResqueScheduler
|
|
59
57
|
def schedule
|
60
58
|
@schedule ||= {}
|
61
59
|
end
|
62
|
-
|
60
|
+
|
63
61
|
# reloads the schedule from redis
|
64
62
|
def reload_schedule!
|
65
63
|
@schedule = get_schedules
|
66
64
|
end
|
67
|
-
|
65
|
+
|
68
66
|
# gets the schedule as it exists in redis
|
69
67
|
def get_schedules
|
70
68
|
if redis.exists(:schedules)
|
@@ -77,12 +75,12 @@ module ResqueScheduler
|
|
77
75
|
nil
|
78
76
|
end
|
79
77
|
end
|
80
|
-
|
78
|
+
|
81
79
|
# Create or update a schedule with the provided name and configuration.
|
82
80
|
#
|
83
81
|
# Note: values for class and custom_job_class need to be strings,
|
84
82
|
# not constants.
|
85
|
-
#
|
83
|
+
#
|
86
84
|
# Resque.set_schedule('some_job', {:class => 'SomeJob',
|
87
85
|
# :every => '15mins',
|
88
86
|
# :queue => 'high',
|
@@ -95,12 +93,12 @@ module ResqueScheduler
|
|
95
93
|
end
|
96
94
|
config
|
97
95
|
end
|
98
|
-
|
96
|
+
|
99
97
|
# retrive the schedule configuration for the given name
|
100
98
|
def get_schedule(name)
|
101
99
|
decode(redis.hget(:schedules, name))
|
102
100
|
end
|
103
|
-
|
101
|
+
|
104
102
|
# remove a given schedule by name
|
105
103
|
def remove_schedule(name)
|
106
104
|
redis.hdel(:schedules, name)
|
@@ -113,17 +111,23 @@ module ResqueScheduler
|
|
113
111
|
# sit in the schedule list.
|
114
112
|
def enqueue_at(timestamp, klass, *args)
|
115
113
|
validate_job!(klass)
|
116
|
-
enqueue_at_with_queue(
|
114
|
+
enqueue_at_with_queue(queue_from_class(klass), timestamp, klass, *args)
|
117
115
|
end
|
118
116
|
|
119
117
|
# Identical to +enqueue_at+, except you can also specify
|
120
|
-
# a queue in which the job will be placed after the
|
121
|
-
# timestamp has passed.
|
118
|
+
# a queue in which the job will be placed after the
|
119
|
+
# timestamp has passed. It respects Resque.inline option, by
|
120
|
+
# creating the job right away instead of adding to the queue.
|
122
121
|
def enqueue_at_with_queue(queue, timestamp, klass, *args)
|
123
122
|
return false unless Plugin.run_before_schedule_hooks(klass, *args)
|
124
|
-
|
125
|
-
|
126
|
-
|
123
|
+
|
124
|
+
if Resque.inline?
|
125
|
+
# Just create the job and let resque perform it right away with inline.
|
126
|
+
Resque::Job.create(queue, klass, *args)
|
127
|
+
else
|
128
|
+
delayed_push(timestamp, job_to_hash_with_queue(queue, klass, args))
|
129
|
+
end
|
130
|
+
|
127
131
|
Plugin.run_after_schedule_hooks(klass, *args)
|
128
132
|
end
|
129
133
|
|
@@ -134,7 +138,7 @@ module ResqueScheduler
|
|
134
138
|
end
|
135
139
|
|
136
140
|
# Identical to +enqueue_in+, except you can also specify
|
137
|
-
# a queue in which the job will be placed after the
|
141
|
+
# a queue in which the job will be placed after the
|
138
142
|
# number of seconds has passed.
|
139
143
|
def enqueue_in_with_queue(queue, number_of_seconds_from_now, klass, *args)
|
140
144
|
enqueue_at_with_queue(queue, Time.now + number_of_seconds_from_now, klass, *args)
|
@@ -156,7 +160,7 @@ module ResqueScheduler
|
|
156
160
|
|
157
161
|
# Returns an array of timestamps based on start and count
|
158
162
|
def delayed_queue_peek(start, count)
|
159
|
-
Array(redis.zrange(:delayed_queue_schedule, start, start+count)).collect{|x| x.to_i}
|
163
|
+
Array(redis.zrange(:delayed_queue_schedule, start, start+count-1)).collect{|x| x.to_i}
|
160
164
|
end
|
161
165
|
|
162
166
|
# Returns the size of the delayed queue schedule
|
@@ -210,7 +214,7 @@ module ResqueScheduler
|
|
210
214
|
end
|
211
215
|
|
212
216
|
# Given an encoded item, remove it from the delayed_queue
|
213
|
-
#
|
217
|
+
#
|
214
218
|
# This method is potentially very expensive since it needs to scan
|
215
219
|
# through the delayed queue for every timestamp.
|
216
220
|
def remove_delayed(klass, *args)
|
@@ -221,7 +225,7 @@ module ResqueScheduler
|
|
221
225
|
end
|
222
226
|
destroyed
|
223
227
|
end
|
224
|
-
|
228
|
+
|
225
229
|
# Given a timestamp and job (klass + args) it removes all instances and
|
226
230
|
# returns the count of jobs removed.
|
227
231
|
#
|
@@ -238,28 +242,32 @@ module ResqueScheduler
|
|
238
242
|
total_jobs = 0
|
239
243
|
Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |timestamp|
|
240
244
|
total_jobs += redis.llen("delayed:#{timestamp}").to_i
|
241
|
-
end
|
245
|
+
end
|
242
246
|
total_jobs
|
243
|
-
end
|
247
|
+
end
|
244
248
|
|
245
249
|
private
|
246
|
-
|
250
|
+
|
247
251
|
def job_to_hash(klass, args)
|
248
252
|
{:class => klass.to_s, :args => args, :queue => queue_from_class(klass)}
|
249
253
|
end
|
250
|
-
|
254
|
+
|
251
255
|
def job_to_hash_with_queue(queue, klass, args)
|
252
256
|
{:class => klass.to_s, :args => args, :queue => queue}
|
253
257
|
end
|
254
258
|
|
255
259
|
def clean_up_timestamp(key, timestamp)
|
256
260
|
# If the list is empty, remove it.
|
261
|
+
redis.watch key
|
257
262
|
if 0 == redis.llen(key).to_i
|
258
|
-
redis.
|
259
|
-
|
263
|
+
redis.multi do
|
264
|
+
redis.del key
|
265
|
+
redis.zrem :delayed_queue_schedule, timestamp.to_i
|
266
|
+
end
|
267
|
+
else
|
268
|
+
redis.unwatch
|
260
269
|
end
|
261
270
|
end
|
262
|
-
|
263
271
|
def validate_job!(klass)
|
264
272
|
if klass.to_s.empty?
|
265
273
|
raise Resque::NoClassError.new("Jobs must be given a class.")
|
@@ -283,6 +291,3 @@ module ResqueScheduler
|
|
283
291
|
end
|
284
292
|
|
285
293
|
Resque.extend ResqueScheduler
|
286
|
-
Resque::Server.class_eval do
|
287
|
-
include ResqueScheduler::Server
|
288
|
-
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'resque_scheduler'
|
2
|
+
require 'resque/server'
|
1
3
|
|
2
4
|
# Extend Resque::Server to add tabs
|
3
5
|
module ResqueScheduler
|
4
|
-
|
6
|
+
|
5
7
|
module Server
|
6
8
|
|
7
9
|
def self.included(base)
|
@@ -29,7 +31,7 @@ module ResqueScheduler
|
|
29
31
|
Resque::Scheduler.enqueue_from_config(config)
|
30
32
|
redirect u("/overview")
|
31
33
|
end
|
32
|
-
|
34
|
+
|
33
35
|
get "/delayed" do
|
34
36
|
# Is there a better way to specify alternate template locations with sinatra?
|
35
37
|
erb File.read(File.join(File.dirname(__FILE__), 'server/views/delayed.erb'))
|
@@ -39,13 +41,13 @@ module ResqueScheduler
|
|
39
41
|
# Is there a better way to specify alternate template locations with sinatra?
|
40
42
|
erb File.read(File.join(File.dirname(__FILE__), 'server/views/delayed_timestamp.erb'))
|
41
43
|
end
|
42
|
-
|
44
|
+
|
43
45
|
post "/delayed/queue_now" do
|
44
46
|
timestamp = params['timestamp']
|
45
47
|
Resque::Scheduler.enqueue_delayed_items_for_timestamp(timestamp.to_i) if timestamp.to_i > 0
|
46
48
|
redirect u("/overview")
|
47
49
|
end
|
48
|
-
|
50
|
+
|
49
51
|
post "/delayed/clear" do
|
50
52
|
Resque.reset_delayed_queue
|
51
53
|
redirect u('delayed')
|
@@ -59,5 +61,9 @@ module ResqueScheduler
|
|
59
61
|
Resque::Server.tabs << 'Delayed'
|
60
62
|
|
61
63
|
end
|
62
|
-
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
Resque::Server.class_eval do
|
68
|
+
include ResqueScheduler::Server
|
63
69
|
end
|
data/resque-scheduler.gemspec
CHANGED
@@ -22,6 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.require_path = 'lib'
|
23
23
|
|
24
24
|
s.add_runtime_dependency(%q<redis>, [">= 2.0.1"])
|
25
|
-
s.add_runtime_dependency(%q<resque>, [">= 1.
|
25
|
+
s.add_runtime_dependency(%q<resque>, [">= 1.20.0"])
|
26
26
|
s.add_runtime_dependency(%q<rufus-scheduler>, [">= 0"])
|
27
27
|
end
|
data/test/delayed_queue_test.rb
CHANGED
@@ -110,9 +110,9 @@ context "DelayedQueue" do
|
|
110
110
|
Resque.delayed_push(timestamp, {:class => SomeIvarJob, :args => 'blah1'})
|
111
111
|
end
|
112
112
|
|
113
|
-
timestamps = Resque.delayed_queue_peek(2
|
113
|
+
timestamps = Resque.delayed_queue_peek(1,2)
|
114
114
|
|
115
|
-
assert_equal(expected_timestamps[2
|
115
|
+
assert_equal(expected_timestamps[1,2], timestamps)
|
116
116
|
end
|
117
117
|
|
118
118
|
test "delayed_queue_schedule_size returns correct size" do
|
@@ -123,26 +123,26 @@ context "DelayedQueue" do
|
|
123
123
|
|
124
124
|
test "delayed_timestamp_size returns 0 when nothing is queue" do
|
125
125
|
t = Time.now + 60
|
126
|
-
assert_equal(0, Resque.delayed_timestamp_size(t))
|
126
|
+
assert_equal(0, Resque.delayed_timestamp_size(t))
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
test "delayed_timestamp_size returns 1 when one thing is queued" do
|
130
130
|
t = Time.now + 60
|
131
131
|
Resque.enqueue_at(t, SomeIvarJob)
|
132
|
-
assert_equal(1, Resque.delayed_timestamp_size(t))
|
132
|
+
assert_equal(1, Resque.delayed_timestamp_size(t))
|
133
133
|
end
|
134
134
|
|
135
135
|
test "delayed_timestamp_peek returns empty array when nothings in it" do
|
136
136
|
t = Time.now + 60
|
137
137
|
assert_equal([], Resque.delayed_timestamp_peek(t, 0, 1), "make sure it's an empty array, not nil")
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
test "delayed_timestamp_peek returns an array containing one job when one thing is queued" do
|
141
141
|
t = Time.now + 60
|
142
142
|
Resque.enqueue_at(t, SomeIvarJob)
|
143
143
|
assert_equal [{'args' => [], 'class' => 'SomeIvarJob', 'queue' => 'ivar'}], Resque.delayed_timestamp_peek(t, 0, 1)
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
test "delayed_timestamp_peek returns an array of multiple jobs when more than one job is queued" do
|
147
147
|
t = Time.now + 60
|
148
148
|
Resque.enqueue_at(t, SomeIvarJob)
|
@@ -150,7 +150,7 @@ context "DelayedQueue" do
|
|
150
150
|
job = {'args' => [], 'class' => 'SomeIvarJob', 'queue' => 'ivar'}
|
151
151
|
assert_equal([job, job], Resque.delayed_timestamp_peek(t, 0, 2))
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
test "delayed_timestamp_peek only returns an array of one job if only asked for 1" do
|
155
155
|
t = Time.now + 60
|
156
156
|
Resque.enqueue_at(t, SomeIvarJob)
|
@@ -170,7 +170,7 @@ context "DelayedQueue" do
|
|
170
170
|
Resque.enqueue_at(t, SomeIvarJob)
|
171
171
|
|
172
172
|
# 2 SomeIvarJob jobs should be created in the "ivar" queue
|
173
|
-
Resque::Job.expects(:create).twice.with(
|
173
|
+
Resque::Job.expects(:create).twice.with('ivar', SomeIvarJob, nil)
|
174
174
|
Resque::Scheduler.handle_delayed_items
|
175
175
|
end
|
176
176
|
|
@@ -180,7 +180,7 @@ context "DelayedQueue" do
|
|
180
180
|
Resque.enqueue_at(t, SomeIvarJob)
|
181
181
|
|
182
182
|
# 2 SomeIvarJob jobs should be created in the "ivar" queue
|
183
|
-
Resque::Job.expects(:create).twice.with(
|
183
|
+
Resque::Job.expects(:create).twice.with('ivar', SomeIvarJob, nil)
|
184
184
|
Resque::Scheduler.handle_delayed_items(t)
|
185
185
|
end
|
186
186
|
|
@@ -191,7 +191,7 @@ context "DelayedQueue" do
|
|
191
191
|
Resque.enqueue_at(t, SomeIvarJob)
|
192
192
|
|
193
193
|
# 2 SomeIvarJob jobs should be created in the "ivar" queue
|
194
|
-
Resque::Job.expects(:create).twice.with(
|
194
|
+
Resque::Job.expects(:create).twice.with('ivar', SomeIvarJob, nil)
|
195
195
|
|
196
196
|
Resque::Scheduler.enqueue_delayed_items_for_timestamp(t)
|
197
197
|
|
@@ -258,14 +258,14 @@ context "DelayedQueue" do
|
|
258
258
|
assert_equal(2, Resque.remove_delayed(SomeIvarJob, "bar"))
|
259
259
|
assert_equal(2, Resque.count_all_scheduled_jobs)
|
260
260
|
end
|
261
|
-
|
261
|
+
|
262
262
|
test "remove_delayed_job_from_timestamp removes instances of jobs at a given timestamp" do
|
263
263
|
t = Time.now + 120
|
264
264
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
265
265
|
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
266
266
|
assert_equal 0, Resque.delayed_timestamp_size(t)
|
267
267
|
end
|
268
|
-
|
268
|
+
|
269
269
|
test "remove_delayed_job_from_timestamp doesn't remove items from other timestamps" do
|
270
270
|
t1 = Time.now + 120
|
271
271
|
t2 = t1 + 1
|
@@ -275,29 +275,29 @@ context "DelayedQueue" do
|
|
275
275
|
assert_equal 1, Resque.delayed_timestamp_size(t1)
|
276
276
|
assert_equal 0, Resque.delayed_timestamp_size(t2)
|
277
277
|
end
|
278
|
-
|
278
|
+
|
279
279
|
test "remove_delayed_job_from_timestamp removes nothing if there are no matches" do
|
280
280
|
t = Time.now + 120
|
281
281
|
assert_equal 0, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
282
282
|
end
|
283
|
-
|
283
|
+
|
284
284
|
test "remove_delayed_job_from_timestamp only removes items that match args" do
|
285
285
|
t = Time.now + 120
|
286
286
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
287
287
|
Resque.enqueue_at(t, SomeIvarJob, "bar")
|
288
288
|
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
289
|
-
assert_equal 1, Resque.delayed_timestamp_size(t)
|
289
|
+
assert_equal 1, Resque.delayed_timestamp_size(t)
|
290
290
|
end
|
291
|
-
|
291
|
+
|
292
292
|
test "remove_delayed_job_from_timestamp returns the number of items removed" do
|
293
293
|
t = Time.now + 120
|
294
294
|
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
295
295
|
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
296
296
|
end
|
297
|
-
|
297
|
+
|
298
298
|
test "remove_delayed_job_from_timestamp should cleanup the delayed timestamp list if not jobs are left" do
|
299
299
|
t = Time.now + 120
|
300
|
-
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
300
|
+
Resque.enqueue_at(t, SomeIvarJob, "foo")
|
301
301
|
assert_equal 1, Resque.remove_delayed_job_from_timestamp(t, SomeIvarJob, "foo")
|
302
302
|
assert !Resque.redis.exists("delayed:#{t.to_i}")
|
303
303
|
assert Resque.delayed_queue_peek(0, 100).empty?
|
@@ -311,4 +311,19 @@ context "DelayedQueue" do
|
|
311
311
|
Resque.enqueue_in(10, String) # string serves as invalid Job class
|
312
312
|
end
|
313
313
|
end
|
314
|
+
|
315
|
+
test "inlining jobs with Resque.inline config" do
|
316
|
+
begin
|
317
|
+
Resque.inline = true
|
318
|
+
Resque::Job.expects(:create).once.with(:ivar, SomeIvarJob, "foo", "bar")
|
319
|
+
|
320
|
+
timestamp = Time.now + 120
|
321
|
+
Resque.enqueue_at(timestamp, SomeIvarJob, "foo", "bar")
|
322
|
+
|
323
|
+
assert_equal 0, Resque.count_all_scheduled_jobs
|
324
|
+
assert !Resque.redis.exists("delayed:#{timestamp.to_i}")
|
325
|
+
ensure
|
326
|
+
Resque.inline = false
|
327
|
+
end
|
328
|
+
end
|
314
329
|
end
|
data/test/scheduler_test.rb
CHANGED
@@ -32,6 +32,14 @@ context "Resque::Scheduler" do
|
|
32
32
|
Resque::Scheduler.enqueue_from_config(config)
|
33
33
|
end
|
34
34
|
|
35
|
+
test "enqueue_from_config respects queue params" do
|
36
|
+
config = {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'queue' => 'high'}
|
37
|
+
|
38
|
+
Resque.expects(:enqueue_to).with('high', SomeIvarJob)
|
39
|
+
|
40
|
+
Resque::Scheduler.enqueue_from_config(config)
|
41
|
+
end
|
42
|
+
|
35
43
|
test "config makes it into the rufus_scheduler" do
|
36
44
|
assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
|
37
45
|
|
data/test/test_helper.rb
CHANGED
@@ -8,9 +8,9 @@ require 'rubygems'
|
|
8
8
|
require 'test/unit'
|
9
9
|
require 'mocha'
|
10
10
|
require 'resque'
|
11
|
-
require File.join(dir, '../lib/resque_scheduler')
|
12
11
|
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
|
13
|
-
|
12
|
+
require 'resque_scheduler'
|
13
|
+
require 'resque_scheduler/server'
|
14
14
|
|
15
15
|
#
|
16
16
|
# make sure we can run redis
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ben VandenBos
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 1.0.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: redis
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,21 +37,31 @@ dependencies:
|
|
32
37
|
version: 2.0.1
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.0.1
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: resque
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.
|
53
|
+
version: 1.20.0
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.20.0
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: rufus-scheduler
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,7 +69,12 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
description: ! "Light weight job scheduling on top of Resque.\n Adds methods enqueue_at/enqueue_in
|
59
79
|
to schedule jobs in the future.\n Also supports queueing jobs on a fixed, cron-like
|
60
80
|
schedule."
|
@@ -100,9 +120,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
120
|
- - ! '>='
|
101
121
|
- !ruby/object:Gem::Version
|
102
122
|
version: '0'
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
hash: -2739279222393439195
|
106
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
124
|
none: false
|
108
125
|
requirements:
|
@@ -111,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
128
|
version: 1.3.6
|
112
129
|
requirements: []
|
113
130
|
rubyforge_project:
|
114
|
-
rubygems_version: 1.8.
|
131
|
+
rubygems_version: 1.8.21
|
115
132
|
signing_key:
|
116
133
|
specification_version: 3
|
117
134
|
summary: Light weight job scheduling on top of Resque
|