resque-scheduler 2.0.0.d → 2.0.0.e
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.lock +13 -21
- data/HISTORY.md +8 -0
- data/README.markdown +141 -165
- data/Rakefile +8 -0
- data/lib/resque/scheduler.rb +54 -20
- data/lib/resque_scheduler.rb +47 -12
- data/lib/resque_scheduler/server.rb +5 -0
- data/lib/resque_scheduler/server/views/delayed.erb +8 -2
- data/lib/resque_scheduler/tasks.rb +2 -1
- data/lib/resque_scheduler/version.rb +1 -1
- data/resque-scheduler.gemspec +3 -4
- data/test/delayed_queue_test.rb +37 -12
- data/test/scheduler_args_test.rb +10 -0
- data/test/scheduler_test.rb +51 -32
- data/test/test_helper.rb +11 -5
- metadata +71 -108
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
resque-scheduler (
|
4
|
+
resque-scheduler (2.0.0.e)
|
5
5
|
redis (>= 2.0.1)
|
6
|
-
resque (>= 1.
|
6
|
+
resque (>= 1.15.0)
|
7
7
|
rufus-scheduler
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
11
11
|
specs:
|
12
|
-
git (1.2.5)
|
13
|
-
jeweler (1.5.1)
|
14
|
-
bundler (~> 1.0.0)
|
15
|
-
git (>= 1.2.5)
|
16
|
-
rake
|
17
12
|
json (1.4.6)
|
18
13
|
mocha (0.9.9)
|
19
14
|
rake
|
@@ -21,21 +16,21 @@ GEM
|
|
21
16
|
rack-test (0.5.6)
|
22
17
|
rack (>= 1.0)
|
23
18
|
rake (0.8.7)
|
24
|
-
redis (2.
|
25
|
-
redis-namespace (
|
19
|
+
redis (2.2.2)
|
20
|
+
redis-namespace (1.1.0)
|
26
21
|
redis (< 3.0.0)
|
27
|
-
resque (1.
|
22
|
+
resque (1.15.0)
|
28
23
|
json (~> 1.4.6)
|
29
|
-
redis-namespace (
|
24
|
+
redis-namespace (>= 0.10.0)
|
30
25
|
sinatra (>= 0.9.2)
|
31
26
|
vegas (~> 0.1.2)
|
32
|
-
rufus-scheduler (2.0.
|
33
|
-
tzinfo
|
34
|
-
sinatra (1.
|
27
|
+
rufus-scheduler (2.0.10)
|
28
|
+
tzinfo (>= 0.3.23)
|
29
|
+
sinatra (1.2.6)
|
35
30
|
rack (~> 1.1)
|
36
|
-
tilt (
|
37
|
-
tilt (1.
|
38
|
-
tzinfo (0.3.
|
31
|
+
tilt (>= 1.2.2, < 2.0)
|
32
|
+
tilt (1.3.2)
|
33
|
+
tzinfo (0.3.29)
|
39
34
|
vegas (0.1.8)
|
40
35
|
rack (>= 1.0.0)
|
41
36
|
|
@@ -43,10 +38,7 @@ PLATFORMS
|
|
43
38
|
ruby
|
44
39
|
|
45
40
|
DEPENDENCIES
|
46
|
-
|
41
|
+
bundler (>= 1.0.0)
|
47
42
|
mocha
|
48
43
|
rack-test
|
49
|
-
redis (>= 2.0.1)
|
50
|
-
resque (>= 1.8.0)
|
51
44
|
resque-scheduler!
|
52
|
-
rufus-scheduler
|
data/HISTORY.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
* TODO: address race condition with delayed jobs (using redis transactions)
|
4
4
|
|
5
|
+
## 2.0.0.e (2011-09-16)
|
6
|
+
|
7
|
+
* Adding enqueue_at_with_queue/enqueue_in_with_queue support (niralisse)
|
8
|
+
* Adding `Resque::Scheduler.poll_sleep_amount` to allow for configuring
|
9
|
+
the sleep time b/w delayed queue polls.
|
10
|
+
* Add a "Clear Delayed Jobs" button to the Delayed Jobs page (john-griffin)
|
11
|
+
* Fixed pagination issue on the Delayed tab
|
12
|
+
|
5
13
|
## 2.0.0.d (2011-04-04)
|
6
14
|
|
7
15
|
* porting bug fixes from v1.9-stable
|
data/README.markdown
CHANGED
@@ -1,78 +1,125 @@
|
|
1
1
|
resque-scheduler
|
2
|
-
|
2
|
+
================
|
3
|
+
|
4
|
+
### Description
|
3
5
|
|
4
6
|
Resque-scheduler is an extension to [Resque](http://github.com/defunkt/resque)
|
5
7
|
that adds support for queueing items in the future.
|
6
8
|
|
7
9
|
Requires redis >=1.3.
|
8
10
|
|
11
|
+
Job scheduling is supported in two different way: Recurring (scheduled) and
|
12
|
+
Delayed.
|
9
13
|
|
10
|
-
|
14
|
+
Scheduled jobs are like cron jobs, recurring on a regular basis. Delayed
|
15
|
+
jobs are resque jobs that you want to run at some point in the future.
|
16
|
+
The syntax is pretty explanatory:
|
11
17
|
|
12
|
-
|
18
|
+
Resque.enqueue_in(5.days, SendFollowupEmail) # run a job in 5 days
|
19
|
+
# or
|
20
|
+
Resque.enqueue_at(5.days.from_now, SomeJob) # run SomeJob at a specific time
|
13
21
|
|
14
|
-
|
15
|
-
job. They are jobs that run based on a fixed schedule which is set at startup.
|
22
|
+
### Documentation
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
is most likely stored in a YAML like so:
|
24
|
+
This README covers what most people need to know. If you're looking for
|
25
|
+
details on individual methods, you might want to try the [rdoc](http://rdoc.info/github/bvandenbos/resque-scheduler/master/frames).
|
20
26
|
|
21
|
-
|
22
|
-
cron: "0 0 * * *"
|
23
|
-
class: QueueDocuments
|
24
|
-
args:
|
25
|
-
description: "This job queues all content for indexing in solr"
|
27
|
+
### Installation
|
26
28
|
|
27
|
-
|
28
|
-
cron: "30 6 * * 1"
|
29
|
-
class: ClearLeaderboards
|
30
|
-
args: contributors
|
31
|
-
description: "This job resets the weekly leaderboard for contributions"
|
29
|
+
To install:
|
32
30
|
|
33
|
-
|
34
|
-
queue if it is available (Even if @queue is specified in the job class). When
|
35
|
-
the queue is given it is not necessary for the scheduler to load the class.
|
31
|
+
gem install resque-scheduler
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
Adding the resque:scheduler rake task:
|
34
|
+
|
35
|
+
require 'resque_scheduler/tasks'
|
36
|
+
|
37
|
+
There are three things `resque-scheduler` needs to know about in order to do
|
38
|
+
it's jobs: the schedule, where redis lives, and which queues to use. The
|
39
|
+
easiest way to configure these things is via the rake task. By default,
|
40
|
+
`resque-scheduler` depends on the "resque:setup" rake task. Since you
|
41
|
+
probably already have this task, lets just put our configuration there.
|
42
|
+
`resque-scheduler` pretty much needs to know everything `resque` needs
|
43
|
+
to know.
|
44
|
+
|
45
|
+
|
46
|
+
# Resque tasks
|
47
|
+
require 'resque/tasks'
|
48
|
+
require 'resque_scheduler/tasks'
|
49
|
+
|
50
|
+
namespace :resque do
|
51
|
+
task :setup do
|
52
|
+
require 'resque'
|
53
|
+
require 'resque_scheduler'
|
54
|
+
require 'resque/scheduler'
|
55
|
+
|
56
|
+
# you probably already have this somewhere
|
57
|
+
Resque.redis = 'localhost:6379'
|
58
|
+
|
59
|
+
# The schedule doesn't need to be stored in a YAML, it just needs to
|
60
|
+
# be a hash. YAML is usually the easiest.
|
61
|
+
Resque.schedule = YAML.load_file('your_resque_schedule.yml')
|
62
|
+
|
63
|
+
# If your schedule already has +queue+ set for each job, you don't
|
64
|
+
# need to require your jobs. This can be an advantage since it's
|
65
|
+
# less code that resque-scheduler needs to know about. But in a small
|
66
|
+
# project, it's usually easier to just include you job classes here.
|
67
|
+
# 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
|
77
|
+
end
|
78
|
+
end
|
43
79
|
|
44
|
-
|
80
|
+
The scheduler process is just a rake task which is responsible for both
|
81
|
+
queueing items from the schedule and polling the delayed queue for items
|
82
|
+
ready to be pushed on to the work queues. For obvious reasons, this process
|
83
|
+
never exits.
|
45
84
|
|
46
|
-
|
47
|
-
|
85
|
+
$ rake resque:scheduler
|
86
|
+
|
87
|
+
Supported environment variables are `VERBOSE` and `MUTE`. If either is set to
|
88
|
+
any nonempty value, they will take effect. `VERBOSE` simply dumps more output
|
89
|
+
to stdout. `MUTE` does the opposite and silences all output. `MUTE`
|
90
|
+
supersedes `VERBOSE`.
|
91
|
+
|
92
|
+
NOTE: You DO NOT want to run >1 instance of the scheduler. Doing so will
|
93
|
+
result in the same job being queued more than once. You only need one
|
94
|
+
instnace of the scheduler running per resque instance (regardless of number
|
95
|
+
of machines).
|
96
|
+
|
97
|
+
If the scheduler process goes down for whatever reason, the delayed items
|
98
|
+
that should have fired during the outage will fire once the scheduler process
|
99
|
+
is started back up again (regardless of it being on a new machine). Missed
|
100
|
+
scheduled jobs, however, will not fire upon recovery of the scheduler process.
|
48
101
|
|
49
|
-
Keep in mind, scheduled jobs behave like crons: if your scheduler process (more
|
50
|
-
on that later) is not running when a particular job is supposed to be queued,
|
51
|
-
it will NOT be ran later when the scheduler process is started back up. In that
|
52
|
-
sense, you can sort of think of the scheduler process as crond. Delayed jobs,
|
53
|
-
however, are different.
|
54
102
|
|
55
|
-
A big shout out to [rufus-scheduler](http://github.com/jmettraux/rufus-scheduler)
|
56
|
-
for handling the heavy lifting of the actual scheduling engine.
|
57
103
|
|
58
104
|
### Delayed jobs
|
59
105
|
|
60
106
|
Delayed jobs are one-off jobs that you want to be put into a queue at some point
|
61
107
|
in the future. The classic example is sending email:
|
62
108
|
|
63
|
-
Resque.
|
109
|
+
Resque.enqueue_in(5.days, SendFollowUpEmail, :user_id => current_user.id)
|
64
110
|
|
65
|
-
This will store the job for 5 days in the resque delayed queue at which time
|
66
|
-
scheduler process will pull it from the delayed queue and put it in the
|
111
|
+
This will store the job for 5 days in the resque delayed queue at which time
|
112
|
+
the scheduler process will pull it from the delayed queue and put it in the
|
67
113
|
appropriate work queue for the given job and it will be processed as soon as
|
68
|
-
a worker is available.
|
114
|
+
a worker is available (just like any other resque job).
|
69
115
|
|
70
116
|
NOTE: The job does not fire **exactly** at the time supplied. Rather, once that
|
71
117
|
time is in the past, the job moves from the delayed queue to the actual resque
|
72
118
|
work queue and will be completed as workers as free to process it.
|
73
119
|
|
74
|
-
Also supported is `Resque.
|
75
|
-
|
120
|
+
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
|
122
|
+
queue name.
|
76
123
|
|
77
124
|
The delayed queue is stored in redis and is persisted in the same way the
|
78
125
|
standard resque jobs are persisted (redis writing to disk). Delayed jobs differ
|
@@ -86,57 +133,57 @@ since the jobs are stored in a redis sorted set (zset). I can't imagine this
|
|
86
133
|
being an issue for someone since redis is stupidly fast even at log(n), but full
|
87
134
|
disclosure is always best.
|
88
135
|
|
89
|
-
|
136
|
+
##### Removing Delayed jobs
|
90
137
|
|
91
|
-
If you have the need to cancel a delayed job, you can do so
|
138
|
+
If you have the need to cancel a delayed job, you can do like so:
|
92
139
|
|
93
140
|
# after you've enqueued a job like:
|
94
141
|
Resque.enqueue_at(5.days.from_now, SendFollowUpEmail, :user_id => current_user.id)
|
95
142
|
# remove the job with exactly the same parameters:
|
96
143
|
Resque.remove_delayed(SendFollowUpEmail, :user_id => current_user.id)
|
97
144
|
|
145
|
+
### Scheduled Jobs (Recurring Jobs)
|
98
146
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
defined and updated inside of your application. A good example is if you want
|
103
|
-
to allow users to configured when a report is automatically generated. This
|
104
|
-
can be completed by loading the schedule initially wherever you configure
|
105
|
-
Resque and setting `Resque::Scheduler.dynamic` to `true`. Then subsequently
|
106
|
-
updating the "`schedules`" key in redis, namespaced to the Resque namespace.
|
107
|
-
The "`schedules`" key is expected to be a redis hash data type, where the key
|
108
|
-
is the name of the schedule and the value is a JSON encoded hash of the
|
109
|
-
schedule configuration. There are methods on Resque to make this easy (see
|
110
|
-
below).
|
147
|
+
Scheduled (or recurring) jobs are logically no different than a standard cron
|
148
|
+
job. They are jobs that run based on a fixed schedule which is set at
|
149
|
+
startup.
|
111
150
|
|
112
|
-
|
113
|
-
schedule
|
114
|
-
|
115
|
-
need to be changed are stored in the `schedules_changed` set in redis.
|
151
|
+
The schedule is a list of Resque worker classes with arguments and a
|
152
|
+
schedule frequency (in crontab syntax). The schedule is just a hash, but
|
153
|
+
is most likely stored in a YAML like so:
|
116
154
|
|
117
|
-
|
118
|
-
|
119
|
-
|
155
|
+
queue_documents_for_indexing:
|
156
|
+
cron: "0 0 * * *"
|
157
|
+
# you can use rufus-scheduler "every" syntax in place of cron if you prefer
|
158
|
+
# every: 1hr
|
159
|
+
class: QueueDocuments
|
160
|
+
queue: high
|
161
|
+
args:
|
162
|
+
description: "This job queues all content for indexing in solr"
|
120
163
|
|
121
|
-
|
122
|
-
|
164
|
+
clear_leaderboards_contributors:
|
165
|
+
cron: "30 6 * * 1"
|
166
|
+
class: ClearLeaderboards
|
167
|
+
queue: low
|
168
|
+
args: contributors
|
169
|
+
description: "This job resets the weekly leaderboard for contributions"
|
123
170
|
|
124
|
-
|
125
|
-
|
126
|
-
|
171
|
+
The queue value is optional, but if left unspecified resque-scheduler will
|
172
|
+
attempt to get the queue from the job class, which means it needs to be
|
173
|
+
defined. If you're getting "uninitialized constant" errors, you probably
|
174
|
+
need to either set the queue in the schedule or require your jobs in your
|
175
|
+
"resque:setup" rake task.
|
127
176
|
|
128
|
-
|
177
|
+
NOTE: Six parameter cron's are also supported (as they supported by
|
178
|
+
rufus-scheduler which powers the resque-scheduler process). This allows you
|
179
|
+
to schedule jobs per second (ie: "30 * * * * *" would fire a job every 30
|
180
|
+
seconds past the minute).
|
129
181
|
|
130
|
-
|
131
|
-
|
132
|
-
:class => "CreateFakeLeaderboards",
|
133
|
-
:queue => scoring
|
134
|
-
})
|
182
|
+
A big shout out to [rufus-scheduler](http://github.com/jmettraux/rufus-scheduler)
|
183
|
+
for handling the heavy lifting of the actual scheduling engine.
|
135
184
|
|
136
|
-
In this way, it's possible to completely configure your scheduled jobs from
|
137
|
-
inside your app if you so desire.
|
138
185
|
|
139
|
-
|
186
|
+
##### Support for resque-status (and other custom jobs)
|
140
187
|
|
141
188
|
Some Resque extensions like
|
142
189
|
[resque-status](http://github.com/quirkey/resque-status) use custom job
|
@@ -153,6 +200,8 @@ Let's pretend we have a JobWithStatus class called FakeLeaderboard
|
|
153
200
|
end
|
154
201
|
end
|
155
202
|
|
203
|
+
And then a schedule:
|
204
|
+
|
156
205
|
create_fake_leaderboards:
|
157
206
|
cron: "30 6 * * 1"
|
158
207
|
queue: scoring
|
@@ -175,52 +224,8 @@ custom job class to support the #scheduled method:
|
|
175
224
|
end
|
176
225
|
|
177
226
|
|
178
|
-
### Schedule jobs per environment
|
179
|
-
|
180
|
-
Resque-Scheduler allows to create schedule jobs for specific envs. The arg
|
181
|
-
`rails_env` (optional) can be used to determine which envs are concerned by the
|
182
|
-
job:
|
183
|
-
|
184
|
-
create_fake_leaderboards:
|
185
|
-
cron: "30 6 * * 1"
|
186
|
-
class: CreateFakeLeaderboards
|
187
|
-
queue: scoring
|
188
|
-
args:
|
189
|
-
rails_env: demo
|
190
|
-
description: "This job will auto-create leaderboards for our online demo"
|
191
|
-
|
192
|
-
The scheduled job create_fake_leaderboards will be created only if the
|
193
|
-
environment variable `RAILS_ENV` is set to demo:
|
194
|
-
|
195
|
-
$ RAILS_ENV=demo rake resque:scheduler
|
196
|
-
|
197
|
-
NOTE: If you have added the 2 lines bellow to your Rails Rakefile
|
198
|
-
(ie: lib/tasks/resque-scheduler.rake), the rails env is loaded automatically
|
199
|
-
and you don't have to specify RAILS_ENV if the var is correctly set in
|
200
|
-
environment.rb
|
201
|
-
|
202
|
-
Alternatively, you can use your resque initializer to avoid loading the entire
|
203
|
-
rails stack.
|
204
|
-
|
205
|
-
$ rake resque:scheduler INITIALIZER_PATH=config/initializers/resque.rb
|
206
|
-
|
207
|
-
|
208
|
-
Multiple envs are allowed, separated by commas:
|
209
|
-
|
210
|
-
create_fake_leaderboards:
|
211
|
-
cron: "30 6 * * 1"
|
212
|
-
class: CreateFakeLeaderboards
|
213
|
-
queue: scoring
|
214
|
-
args:
|
215
|
-
rails_env: demo, staging, production
|
216
|
-
description: "This job will auto-create leaderboards"
|
217
|
-
|
218
|
-
NOTE: If you specify the `rails_env` arg without setting RAILS_ENV as an
|
219
|
-
environment variable, the job won't be loaded.
|
220
|
-
|
221
227
|
|
222
|
-
|
223
|
-
--------------------
|
228
|
+
### resque-web Additions
|
224
229
|
|
225
230
|
Resque-scheduler also adds to tabs to the resque-web UI. One is for viewing
|
226
231
|
(and manually queueing) the schedule and one is for viewing pending jobs in
|
@@ -234,16 +239,18 @@ The Delayed tab:
|
|
234
239
|
|
235
240
|

|
236
241
|
|
237
|
-
|
238
|
-
include the `resque-scheduler` plugin.
|
239
|
-
|
242
|
+
To get these to show up you need to pass a file to `resque-web` to tell it to
|
243
|
+
include the `resque-scheduler` plugin. Unless you're running redis on
|
244
|
+
localhost, you probably already have this file. It probably looks something
|
245
|
+
like this:
|
240
246
|
|
241
247
|
require 'resque' # include resque so we can configure it
|
242
248
|
Resque.redis = "redis_server:6379" # tell Resque where redis lives
|
243
249
|
|
244
250
|
Now, you want to add the following:
|
245
251
|
|
246
|
-
|
252
|
+
# This will make the tabs show up.
|
253
|
+
require 'resque_scheduler'
|
247
254
|
|
248
255
|
As of resque-scheduler 2.0, it's no longer necessary to have the resque-web
|
249
256
|
process aware of the schedule because it reads it from redis. But prior to
|
@@ -258,42 +265,7 @@ Now make sure you're passing that file to resque-web like so:
|
|
258
265
|
|
259
266
|
That should make the scheduler tabs show up in `resque-web`.
|
260
267
|
|
261
|
-
|
262
|
-
Installation and the Scheduler process
|
263
|
-
--------------------------------------
|
264
|
-
|
265
|
-
To install:
|
266
|
-
|
267
|
-
gem install resque-scheduler
|
268
|
-
|
269
|
-
The unless you specify the `queue` for each scheduled job, the scheduler
|
270
|
-
needs to know about your job classes (so it can put them into the appropriate
|
271
|
-
queue). To do so, extend the "resque:scheduler_setup" to load your app's code.
|
272
|
-
In rails, it would look something like this:
|
273
|
-
|
274
|
-
require 'resque_scheduler/tasks'
|
275
|
-
task "resque:scheduler_setup" => :environment # load the env so we know about the job classes
|
276
|
-
|
277
|
-
By default, "resque:scheduler_setup" invokes "resque:setup".
|
278
|
-
|
279
|
-
The scheduler process is just a rake task which is responsible for both queueing
|
280
|
-
items from the schedule and polling the delayed queue for items ready to be
|
281
|
-
pushed on to the work queues. For obvious reasons, this process never exits.
|
282
|
-
|
283
|
-
$ rake resque:scheduler
|
284
|
-
|
285
|
-
Supported environment variables are `VERBOSE` and `MUTE`. If either is set to
|
286
|
-
any nonempty value, they will take effect. `VERBOSE` simply dumps more output
|
287
|
-
to stdout. `MUTE` does the opposite and silences all output. `MUTE` supersedes
|
288
|
-
`VERBOSE`.
|
289
|
-
|
290
|
-
NOTE: You DO NOT want to run >1 instance of the scheduler. Doing so will result
|
291
|
-
in the same job being queued more than once. You only need one instnace of the
|
292
|
-
scheduler running per resque instance (regardless of number of machines).
|
293
|
-
|
294
|
-
|
295
|
-
Plagurism alert
|
296
|
-
---------------
|
268
|
+
### Plagiarism alert
|
297
269
|
|
298
270
|
This was intended to be an extension to resque and so resulted in a lot of the
|
299
271
|
code looking very similar to resque, particularly in resque-web and the views. I
|
@@ -301,7 +273,11 @@ wanted it to be similar enough that someone familiar with resque could easily
|
|
301
273
|
work on resque-scheduler.
|
302
274
|
|
303
275
|
|
304
|
-
Contributing
|
305
|
-
------------
|
276
|
+
### Contributing
|
306
277
|
|
307
278
|
For bugs or suggestions, please just open an issue in github.
|
279
|
+
|
280
|
+
Patches are always welcome.
|
281
|
+
|
282
|
+
|
283
|
+
|