resque-scheduler 1.9.10 → 2.0.0.a
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 +0 -3
- data/Gemfile +1 -2
- data/Gemfile.lock +52 -0
- data/HISTORY.md +3 -14
- data/README.markdown +98 -44
- data/Rakefile +3 -31
- data/lib/resque/scheduler.rb +98 -42
- data/lib/resque_scheduler.rb +48 -34
- data/lib/resque_scheduler/server.rb +8 -7
- data/lib/resque_scheduler/server/views/delayed.erb +3 -3
- data/lib/resque_scheduler/server/views/scheduler.erb +4 -4
- data/lib/resque_scheduler/tasks.rb +1 -1
- data/lib/resque_scheduler/version.rb +1 -1
- data/resque-scheduler.gemspec +23 -26
- data/test/delayed_queue_test.rb +5 -41
- data/test/redis-test.conf +1 -1
- data/test/resque-web_test.rb +2 -3
- data/test/scheduler_args_test.rb +1 -1
- data/test/scheduler_test.rb +159 -6
- data/test/test_helper.rb +8 -8
- metadata +121 -139
- checksums.yaml +0 -7
- data/.rubocop.yml +0 -120
- data/.travis.yml +0 -10
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
resque-scheduler (1.9.7)
|
5
|
+
redis (>= 2.0.1)
|
6
|
+
resque (>= 1.8.0)
|
7
|
+
rufus-scheduler
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
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
|
+
json (1.4.6)
|
18
|
+
mocha (0.9.9)
|
19
|
+
rake
|
20
|
+
rack (1.2.1)
|
21
|
+
rack-test (0.5.6)
|
22
|
+
rack (>= 1.0)
|
23
|
+
rake (0.8.7)
|
24
|
+
redis (2.1.1)
|
25
|
+
redis-namespace (0.8.0)
|
26
|
+
redis (< 3.0.0)
|
27
|
+
resque (1.10.0)
|
28
|
+
json (~> 1.4.6)
|
29
|
+
redis-namespace (~> 0.8.0)
|
30
|
+
sinatra (>= 0.9.2)
|
31
|
+
vegas (~> 0.1.2)
|
32
|
+
rufus-scheduler (2.0.7)
|
33
|
+
tzinfo
|
34
|
+
sinatra (1.1.0)
|
35
|
+
rack (~> 1.1)
|
36
|
+
tilt (~> 1.1)
|
37
|
+
tilt (1.1)
|
38
|
+
tzinfo (0.3.23)
|
39
|
+
vegas (0.1.8)
|
40
|
+
rack (>= 1.0.0)
|
41
|
+
|
42
|
+
PLATFORMS
|
43
|
+
ruby
|
44
|
+
|
45
|
+
DEPENDENCIES
|
46
|
+
jeweler
|
47
|
+
mocha
|
48
|
+
rack-test
|
49
|
+
redis (>= 2.0.1)
|
50
|
+
resque (>= 1.8.0)
|
51
|
+
resque-scheduler!
|
52
|
+
rufus-scheduler
|
data/HISTORY.md
CHANGED
@@ -1,18 +1,7 @@
|
|
1
|
-
##
|
1
|
+
## 2.0.0 (???)
|
2
2
|
|
3
|
-
*
|
4
|
-
*
|
5
|
-
* Mocha setup compatibility
|
6
|
-
* Ruby 1.8 compatibility in scheduler tab when schedule keys are symbols
|
7
|
-
|
8
|
-
## 1.9.9 (2011-03-29)
|
9
|
-
|
10
|
-
* Compatibility with resque 1.15.0
|
11
|
-
|
12
|
-
## 1.9.8 (???)
|
13
|
-
|
14
|
-
* Validates delayed jobs prior to insertion into the delayed queue (bogdan)
|
15
|
-
* Rescue exceptions that occur during queuing and log them (dgrijalva)
|
3
|
+
* Dynamic schedule support (brianjlandau, davidyang)
|
4
|
+
* Now depends on redis >=1.3
|
16
5
|
|
17
6
|
## 1.9.7 (2010-11-09)
|
18
7
|
|
data/README.markdown
CHANGED
@@ -4,7 +4,7 @@ resque-scheduler
|
|
4
4
|
Resque-scheduler is an extension to [Resque](http://github.com/defunkt/resque)
|
5
5
|
that adds support for queueing items in the future.
|
6
6
|
|
7
|
-
Requires redis >=1.
|
7
|
+
Requires redis >=1.3.
|
8
8
|
|
9
9
|
|
10
10
|
Job scheduling is supported in two different way:
|
@@ -30,9 +30,9 @@ is most likely stored in a YAML like so:
|
|
30
30
|
args: contributors
|
31
31
|
description: "This job resets the weekly leaderboard for contributions"
|
32
32
|
|
33
|
-
A queue option can also be specified.
|
34
|
-
if it is available (Even if @queue is specified in the job class). When
|
35
|
-
queue is given it is not necessary for the scheduler to load the class.
|
33
|
+
A queue option can also be specified. Then the job will go onto the specified
|
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.
|
36
36
|
|
37
37
|
clear_leaderboards_moderator:
|
38
38
|
cron: "30 6 * * 1"
|
@@ -95,6 +95,86 @@ If you have the need to cancel a delayed job, you can do so thusly:
|
|
95
95
|
# remove the job with exactly the same parameters:
|
96
96
|
Resque.remove_delayed(SendFollowUpEmail, :user_id => current_user.id)
|
97
97
|
|
98
|
+
|
99
|
+
### Dynamic Schedules
|
100
|
+
|
101
|
+
If needed you can also have recurring jobs (scheduled) that are dynamically
|
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).
|
111
|
+
|
112
|
+
When the scheduler loops it will look for differences between the existing
|
113
|
+
schedule and the current schedule in redis. If there are differences it will
|
114
|
+
make the necessary changes to the running schedule. The schedule names that
|
115
|
+
need to be changed are stored in the `schedules_changed` set in redis.
|
116
|
+
|
117
|
+
To force the scheduler to reload the schedule you just send it the `USR2`
|
118
|
+
signal. This will force a complete schedule reload (unscheduling and
|
119
|
+
rescheduling everything).
|
120
|
+
|
121
|
+
To add/update, delete, and retrieve individual schedule items you should
|
122
|
+
use the provided API methods:
|
123
|
+
|
124
|
+
* `Resque.set_schedule(name, config)`
|
125
|
+
* `Resque.get_schedule(name)`
|
126
|
+
* `Resque.remove_schedule(name)`
|
127
|
+
|
128
|
+
For example:
|
129
|
+
|
130
|
+
Resque.set_schedule("create_fake_leaderboards", {
|
131
|
+
:cron => "30 6 * * 1",
|
132
|
+
:class => "CreateFakeLeaderboards",
|
133
|
+
:queue => scoring
|
134
|
+
})
|
135
|
+
|
136
|
+
In this way, it's possible to completely configure your scheduled jobs from
|
137
|
+
inside your app if you so desire.
|
138
|
+
|
139
|
+
### Support for customized Job classes
|
140
|
+
|
141
|
+
Some Resque extensions like
|
142
|
+
[resque-status](http://github.com/quirkey/resque-status) use custom job
|
143
|
+
classes with a slightly different API signature. Resque-scheduler isn't
|
144
|
+
trying to support all existing and future custom job classes, instead it
|
145
|
+
supports a schedule flag so you can extend your custom class and make it
|
146
|
+
support scheduled job.
|
147
|
+
|
148
|
+
Let's pretend we have a JobWithStatus class called FakeLeaderboard
|
149
|
+
|
150
|
+
class FakeLeaderboard < Resque::JobWithStatus
|
151
|
+
def perform
|
152
|
+
# do something and keep track of the status
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
create_fake_leaderboards:
|
157
|
+
cron: "30 6 * * 1"
|
158
|
+
queue: scoring
|
159
|
+
custom_job_class: FakeLeaderboard
|
160
|
+
args:
|
161
|
+
rails_env: demo
|
162
|
+
description: "This job will auto-create leaderboards for our online demo and the status will update as the worker makes progress"
|
163
|
+
|
164
|
+
If your extension doesn't support scheduled job, you would need to extend the
|
165
|
+
custom job class to support the #scheduled method:
|
166
|
+
|
167
|
+
module Resque
|
168
|
+
class JobWithStatus
|
169
|
+
# Wrapper API to forward a Resque::Job creation API call into
|
170
|
+
# a JobWithStatus call.
|
171
|
+
def self.scheduled(queue, klass, *args)
|
172
|
+
create(args)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
98
178
|
### Schedule jobs per environment
|
99
179
|
|
100
180
|
Resque-Scheduler allows to create schedule jobs for specific envs. The arg
|
@@ -138,39 +218,6 @@ Multiple envs are allowed, separated by commas:
|
|
138
218
|
NOTE: If you specify the `rails_env` arg without setting RAILS_ENV as an
|
139
219
|
environment variable, the job won't be loaded.
|
140
220
|
|
141
|
-
### Support for customized Job classes
|
142
|
-
|
143
|
-
Some Resque extensions like [resque-status](http://github.com/quirkey/resque-status) use custom job classes with a slightly different API signature.
|
144
|
-
Resque-scheduler isn't trying to support all existing and future custom job classes, instead it supports a schedule flag so you can extend your custom class
|
145
|
-
and make it support scheduled job.
|
146
|
-
|
147
|
-
Let's pretend we have a JobWithStatus class called FakeLeaderboard
|
148
|
-
|
149
|
-
class FakeLeaderboard < Resque::JobWithStatus
|
150
|
-
def perform
|
151
|
-
# do something and keep track of the status
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
create_fake_leaderboards:
|
156
|
-
cron: "30 6 * * 1"
|
157
|
-
queue: scoring
|
158
|
-
custom_job_class: FakeLeaderboard
|
159
|
-
args:
|
160
|
-
rails_env: demo
|
161
|
-
description: "This job will auto-create leaderboards for our online demo and the status will update as the worker makes progress"
|
162
|
-
|
163
|
-
If your extension doesn't support scheduled job, you would need to extend the custom job class to support the #scheduled method:
|
164
|
-
|
165
|
-
module Resque
|
166
|
-
class JobWithStatus
|
167
|
-
# Wrapper API to forward a Resque::Job creation API call into a JobWithStatus call.
|
168
|
-
def self.scheduled(queue, klass, *args)
|
169
|
-
create(args)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
221
|
|
175
222
|
Resque-web additions
|
176
223
|
--------------------
|
@@ -188,8 +235,8 @@ The Delayed tab:
|
|
188
235
|

|
189
236
|
|
190
237
|
Get get these to show up you need to pass a file to `resque-web` to tell it to
|
191
|
-
include the `resque-scheduler` plugin. You probably already have a file
|
192
|
-
where you configure `resque`. It probably looks something like this:
|
238
|
+
include the `resque-scheduler` plugin. You probably already have a file
|
239
|
+
somewhere where you configure `resque`. It probably looks something like this:
|
193
240
|
|
194
241
|
require 'resque' # include resque so we can configure it
|
195
242
|
Resque.redis = "redis_server:6379" # tell Resque where redis lives
|
@@ -198,7 +245,10 @@ Now, you want to add the following:
|
|
198
245
|
|
199
246
|
require 'resque_scheduler' # include the resque_scheduler (this makes the tabs show up)
|
200
247
|
|
201
|
-
|
248
|
+
As of resque-scheduler 2.0, it's no longer necessary to have the resque-web
|
249
|
+
process aware of the schedule because it reads it from redis. But prior to
|
250
|
+
2.0, you'll want to make sure you load the schedule in this file as well.
|
251
|
+
Something like this:
|
202
252
|
|
203
253
|
Resque.schedule = YAML.load_file(File.join(RAILS_ROOT, 'config/resque_schedule.yml')) # load the schedule
|
204
254
|
|
@@ -209,7 +259,6 @@ Now make sure you're passing that file to resque-web like so:
|
|
209
259
|
That should make the scheduler tabs show up in `resque-web`.
|
210
260
|
|
211
261
|
|
212
|
-
|
213
262
|
Installation and the Scheduler process
|
214
263
|
--------------------------------------
|
215
264
|
|
@@ -217,10 +266,15 @@ To install:
|
|
217
266
|
|
218
267
|
gem install resque-scheduler
|
219
268
|
|
220
|
-
|
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:
|
221
273
|
|
222
274
|
require 'resque_scheduler/tasks'
|
223
|
-
task "resque:
|
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".
|
224
278
|
|
225
279
|
The scheduler process is just a rake task which is responsible for both queueing
|
226
280
|
items from the schedule and polling the delayed queue for items ready to be
|
@@ -230,7 +284,7 @@ pushed on to the work queues. For obvious reasons, this process never exits.
|
|
230
284
|
|
231
285
|
Supported environment variables are `VERBOSE` and `MUTE`. If either is set to
|
232
286
|
any nonempty value, they will take effect. `VERBOSE` simply dumps more output
|
233
|
-
to stdout. `MUTE` does the opposite and silences all output. `MUTE`
|
287
|
+
to stdout. `MUTE` does the opposite and silences all output. `MUTE` supersedes
|
234
288
|
`VERBOSE`.
|
235
289
|
|
236
290
|
NOTE: You DO NOT want to run >1 instance of the scheduler. Doing so will result
|
data/Rakefile
CHANGED
@@ -1,41 +1,13 @@
|
|
1
|
-
require 'bundler
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
2
3
|
|
3
4
|
$LOAD_PATH.unshift 'lib'
|
4
5
|
|
5
6
|
task :default => :test
|
6
7
|
|
7
|
-
desc
|
8
|
+
desc "Run tests"
|
8
9
|
task :test do
|
9
|
-
if RUBY_VERSION =~ /^1\.8/
|
10
|
-
unless ENV['SEED']
|
11
|
-
srand
|
12
|
-
ENV['SEED'] = (srand % 0xFFFF).to_s
|
13
|
-
end
|
14
|
-
|
15
|
-
$stdout.puts "Running with SEED=#{ENV['SEED']}"
|
16
|
-
srand Integer(ENV['SEED'])
|
17
|
-
elsif ENV['SEED']
|
18
|
-
ARGV += %W(--seed #{ENV['SEED']})
|
19
|
-
end
|
20
10
|
Dir['test/*_test.rb'].each do |f|
|
21
11
|
require File.expand_path(f)
|
22
12
|
end
|
23
13
|
end
|
24
|
-
|
25
|
-
desc 'Run rubocop'
|
26
|
-
task :rubocop do
|
27
|
-
unless RUBY_VERSION < '1.9'
|
28
|
-
sh('rubocop --config .rubocop.yml --format simple') { |r, _| r || abort }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
begin
|
33
|
-
require 'rdoc/task'
|
34
|
-
|
35
|
-
Rake::RDocTask.new do |rd|
|
36
|
-
rd.main = 'README.md'
|
37
|
-
rd.rdoc_files.include('README.md', 'lib/**/*.rb')
|
38
|
-
rd.rdoc_dir = 'doc'
|
39
|
-
end
|
40
|
-
rescue LoadError
|
41
|
-
end
|
data/lib/resque/scheduler.rb
CHANGED
@@ -11,22 +11,32 @@ module Resque
|
|
11
11
|
|
12
12
|
# If true, logs more stuff...
|
13
13
|
attr_accessor :verbose
|
14
|
-
|
14
|
+
|
15
15
|
# If set, produces no output
|
16
16
|
attr_accessor :mute
|
17
|
+
|
18
|
+
# If set, will try to update the schulde in the loop
|
19
|
+
attr_accessor :dynamic
|
20
|
+
|
21
|
+
# the Rufus::Scheduler jobs that are scheduled
|
22
|
+
def scheduled_jobs
|
23
|
+
@@scheduled_jobs
|
24
|
+
end
|
17
25
|
|
18
26
|
# Schedule all jobs and continually look for delayed jobs (never returns)
|
19
27
|
def run
|
20
|
-
|
28
|
+
$0 = "resque-scheduler: Starting"
|
21
29
|
# trap signals
|
22
30
|
register_signal_handlers
|
23
31
|
|
24
32
|
# Load the schedule into rufus
|
33
|
+
procline "Loading Schedule"
|
25
34
|
load_schedule!
|
26
35
|
|
27
36
|
# Now start the scheduling part of the loop.
|
28
37
|
loop do
|
29
38
|
handle_delayed_items
|
39
|
+
update_schedule if dynamic
|
30
40
|
poll_sleep
|
31
41
|
end
|
32
42
|
|
@@ -39,12 +49,13 @@ module Resque
|
|
39
49
|
def register_signal_handlers
|
40
50
|
trap("TERM") { shutdown }
|
41
51
|
trap("INT") { shutdown }
|
42
|
-
|
52
|
+
|
43
53
|
begin
|
44
54
|
trap('QUIT') { shutdown }
|
45
55
|
trap('USR1') { kill_child }
|
56
|
+
trap('USR2') { reload_schedule! }
|
46
57
|
rescue ArgumentError
|
47
|
-
warn "Signals QUIT and USR1 not supported."
|
58
|
+
warn "Signals QUIT and USR1 and USR2 not supported."
|
48
59
|
end
|
49
60
|
end
|
50
61
|
|
@@ -52,29 +63,42 @@ module Resque
|
|
52
63
|
# rufus scheduler instance
|
53
64
|
def load_schedule!
|
54
65
|
log! "Schedule empty! Set Resque.schedule" if Resque.schedule.empty?
|
55
|
-
|
66
|
+
|
67
|
+
@@scheduled_jobs = {}
|
68
|
+
|
56
69
|
Resque.schedule.each do |name, config|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
70
|
+
load_schedule_job(name, config)
|
71
|
+
end
|
72
|
+
Resque.redis.del(:schedules_changed)
|
73
|
+
procline "Schedules Loaded"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Loads a job schedule into the Rufus::Scheduler and stores it in @@scheduled_jobs
|
77
|
+
def load_schedule_job(name, config)
|
78
|
+
# If rails_env is set in the config, enforce ENV['RAILS_ENV'] as
|
79
|
+
# required for the jobs to be scheduled. If rails_env is missing, the
|
80
|
+
# job should be scheduled regardless of what ENV['RAILS_ENV'] is set
|
81
|
+
# to.
|
82
|
+
if config['rails_env'].nil? || rails_env_matches?(config)
|
83
|
+
log! "Scheduling #{name} "
|
84
|
+
interval_defined = false
|
85
|
+
interval_types = %w{cron every}
|
86
|
+
interval_types.each do |interval_type|
|
87
|
+
if !config[interval_type].nil? && config[interval_type].length > 0
|
88
|
+
begin
|
89
|
+
@@scheduled_jobs[name] = rufus_scheduler.send(interval_type, config[interval_type]) do
|
68
90
|
log! "queueing #{config['class']} (#{name})"
|
69
91
|
enqueue_from_config(config)
|
70
92
|
end
|
71
|
-
|
72
|
-
|
93
|
+
rescue Exception => e
|
94
|
+
log! "#{e.class.name}: #{e.message}"
|
73
95
|
end
|
96
|
+
interval_defined = true
|
97
|
+
break
|
74
98
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
99
|
+
end
|
100
|
+
unless interval_defined
|
101
|
+
log! "no #{interval_types.join(' / ')} found for #{config['class']} (#{name}) - skipping"
|
78
102
|
end
|
79
103
|
end
|
80
104
|
end
|
@@ -88,33 +112,30 @@ module Resque
|
|
88
112
|
# Handles queueing delayed items
|
89
113
|
# at_time - Time to start scheduling items (default: now).
|
90
114
|
def handle_delayed_items(at_time=nil)
|
91
|
-
|
92
|
-
|
93
|
-
|
115
|
+
item = nil
|
116
|
+
if timestamp = Resque.next_delayed_timestamp(at_time)
|
117
|
+
procline "Processing Delayed Items"
|
118
|
+
while !timestamp.nil?
|
94
119
|
enqueue_delayed_items_for_timestamp(timestamp)
|
120
|
+
timestamp = Resque.next_delayed_timestamp(at_time)
|
95
121
|
end
|
96
|
-
|
97
|
-
end while !timestamp.nil?
|
122
|
+
end
|
98
123
|
end
|
99
|
-
|
124
|
+
|
100
125
|
# Enqueues all delayed jobs for a timestamp
|
101
126
|
def enqueue_delayed_items_for_timestamp(timestamp)
|
102
127
|
item = nil
|
103
128
|
begin
|
104
129
|
handle_shutdown do
|
105
130
|
if item = Resque.next_item_for_timestamp(timestamp)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
Resque::Job.create(queue, item['class'], *item['args'])
|
115
|
-
end
|
116
|
-
rescue
|
117
|
-
log! "Failed to enqueue #{klass_name}:\n #{$!}"
|
131
|
+
log "queuing #{item['class']} [delayed]"
|
132
|
+
queue = item['queue'] || Resque.queue_from_class(constantize(item['class']))
|
133
|
+
# Support custom job classes like job with status
|
134
|
+
if (job_klass = item['custom_job_class']) && (job_klass != 'Resque::Job')
|
135
|
+
# custom job classes not supporting the same API calls must implement the #schedule method
|
136
|
+
constantize(job_klass).scheduled(queue, item['class'], *item['args'])
|
137
|
+
else
|
138
|
+
Resque::Job.create(queue, item['class'], *item['args'])
|
118
139
|
end
|
119
140
|
end
|
120
141
|
end
|
@@ -140,9 +161,7 @@ module Resque
|
|
140
161
|
constantize(job_klass).scheduled(queue, klass_name, *params)
|
141
162
|
else
|
142
163
|
Resque::Job.create(queue, klass_name, *params)
|
143
|
-
end
|
144
|
-
rescue
|
145
|
-
log! "Failed to enqueue #{klass_name}:\n #{$!}"
|
164
|
+
end
|
146
165
|
end
|
147
166
|
|
148
167
|
def rufus_scheduler
|
@@ -154,8 +173,40 @@ module Resque
|
|
154
173
|
def clear_schedule!
|
155
174
|
rufus_scheduler.stop
|
156
175
|
@rufus_scheduler = nil
|
176
|
+
@@scheduled_jobs = {}
|
157
177
|
rufus_scheduler
|
158
178
|
end
|
179
|
+
|
180
|
+
def reload_schedule!
|
181
|
+
procline "Reloading Schedule"
|
182
|
+
clear_schedule!
|
183
|
+
Resque.reload_schedule!
|
184
|
+
load_schedule!
|
185
|
+
end
|
186
|
+
|
187
|
+
def update_schedule
|
188
|
+
if Resque.redis.scard(:schedules_changed) > 0
|
189
|
+
procline "Updating schedule"
|
190
|
+
Resque.reload_schedule!
|
191
|
+
while schedule_name = Resque.redis.spop(:schedules_changed)
|
192
|
+
if Resque.schedule.keys.include?(schedule_name)
|
193
|
+
unschedule_job(schedule_name)
|
194
|
+
load_schedule_job(schedule_name, Resque.schedule[schedule_name])
|
195
|
+
else
|
196
|
+
unschedule_job(schedule_name)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
procline "Schedules Loaded"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def unschedule_job(name)
|
204
|
+
if scheduled_jobs[name]
|
205
|
+
log "Removing schedule #{name}"
|
206
|
+
scheduled_jobs[name].unschedule
|
207
|
+
@@scheduled_jobs.delete(name)
|
208
|
+
end
|
209
|
+
end
|
159
210
|
|
160
211
|
# Sleeps and returns true
|
161
212
|
def poll_sleep
|
@@ -179,6 +230,11 @@ module Resque
|
|
179
230
|
# add "verbose" logic later
|
180
231
|
log!(msg) if verbose
|
181
232
|
end
|
233
|
+
|
234
|
+
def procline(string)
|
235
|
+
$0 = "resque-scheduler-#{ResqueScheduler::Version}: #{string}"
|
236
|
+
log! $0
|
237
|
+
end
|
182
238
|
|
183
239
|
end
|
184
240
|
|