resque-scheduler 2.5.5 → 3.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.
- checksums.yaml +4 -4
- data/.gitignore +12 -6
- data/.rubocop.yml +18 -113
- data/.rubocop_todo.yml +29 -0
- data/.simplecov +3 -1
- data/.travis.yml +12 -4
- data/.vagrant-provision-as-vagrant.sh +15 -0
- data/.vagrant-provision.sh +23 -0
- data/.vagrant-skel/bash_profile +7 -0
- data/.vagrant-skel/bashrc +7 -0
- data/AUTHORS.md +5 -0
- data/Gemfile +1 -2
- data/HISTORY.md +18 -0
- data/README.md +39 -11
- data/ROADMAP.md +0 -6
- data/Rakefile +11 -19
- data/Vagrantfile +14 -0
- data/bin/resque-scheduler +2 -2
- data/examples/Rakefile +1 -1
- data/examples/config/initializers/resque-web.rb +2 -2
- data/examples/dynamic-scheduling/app/jobs/fix_schedules_job.rb +2 -4
- data/examples/dynamic-scheduling/app/jobs/send_email_job.rb +1 -1
- data/examples/dynamic-scheduling/app/models/user.rb +2 -2
- data/examples/dynamic-scheduling/lib/tasks/resque.rake +2 -2
- data/lib/resque-scheduler.rb +3 -1
- data/lib/resque/scheduler.rb +112 -168
- data/lib/resque/scheduler/cli.rb +144 -0
- data/lib/resque/scheduler/configuration.rb +73 -0
- data/lib/resque/scheduler/delaying_extensions.rb +278 -0
- data/lib/resque/scheduler/env.rb +61 -0
- data/lib/resque/scheduler/extension.rb +13 -0
- data/lib/resque/scheduler/lock.rb +2 -1
- data/lib/resque/scheduler/lock/base.rb +6 -2
- data/lib/resque/scheduler/lock/basic.rb +4 -5
- data/lib/resque/scheduler/lock/resilient.rb +30 -37
- data/lib/resque/scheduler/locking.rb +94 -0
- data/lib/resque/scheduler/logger_builder.rb +72 -0
- data/lib/resque/scheduler/plugin.rb +31 -0
- data/lib/resque/scheduler/scheduling_extensions.rb +150 -0
- data/lib/resque/scheduler/server.rb +246 -0
- data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed.erb +2 -1
- data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed_schedules.erb +0 -0
- data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed_timestamp.erb +0 -0
- data/lib/{resque_scheduler → resque/scheduler}/server/views/requeue-params.erb +0 -0
- data/lib/{resque_scheduler → resque/scheduler}/server/views/scheduler.erb +16 -1
- data/lib/{resque_scheduler → resque/scheduler}/server/views/search.erb +2 -1
- data/lib/{resque_scheduler → resque/scheduler}/server/views/search_form.erb +0 -0
- data/lib/resque/scheduler/signal_handling.rb +40 -0
- data/lib/{resque_scheduler → resque/scheduler}/tasks.rb +3 -5
- data/lib/resque/scheduler/util.rb +41 -0
- data/lib/resque/scheduler/version.rb +7 -0
- data/resque-scheduler.gemspec +21 -19
- data/script/migrate_to_timestamps_set.rb +5 -3
- data/tasks/resque_scheduler.rake +1 -1
- data/test/cli_test.rb +26 -69
- data/test/delayed_queue_test.rb +262 -169
- data/test/env_test.rb +41 -0
- data/test/resque-web_test.rb +169 -48
- data/test/scheduler_args_test.rb +73 -41
- data/test/scheduler_hooks_test.rb +9 -8
- data/test/scheduler_locking_test.rb +55 -36
- data/test/scheduler_setup_test.rb +52 -15
- data/test/scheduler_task_test.rb +15 -10
- data/test/scheduler_test.rb +215 -114
- data/test/support/redis_instance.rb +32 -33
- data/test/test_helper.rb +33 -36
- data/test/util_test.rb +11 -0
- metadata +113 -57
- data/lib/resque/scheduler_locking.rb +0 -91
- data/lib/resque_scheduler.rb +0 -386
- data/lib/resque_scheduler/cli.rb +0 -160
- data/lib/resque_scheduler/logger_builder.rb +0 -72
- data/lib/resque_scheduler/plugin.rb +0 -28
- data/lib/resque_scheduler/server.rb +0 -183
- data/lib/resque_scheduler/util.rb +0 -34
- data/lib/resque_scheduler/version.rb +0 -5
- data/test/redis-test.conf +0 -108
data/ROADMAP.md
CHANGED
data/Rakefile
CHANGED
@@ -1,29 +1,21 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
1
2
|
require 'bundler/gem_tasks'
|
2
3
|
require 'rake/testtask'
|
4
|
+
require 'rubocop/rake_task'
|
5
|
+
require 'yard'
|
3
6
|
|
4
|
-
task default: [:rubocop, :test]
|
7
|
+
task default: [:rubocop, :test] unless RUBY_PLATFORM =~ /java/
|
8
|
+
task default: [:test] if RUBY_PLATFORM =~ /java/
|
9
|
+
|
10
|
+
Rubocop::RakeTask.new
|
5
11
|
|
6
12
|
Rake::TestTask.new do |t|
|
7
13
|
t.libs << 'test'
|
8
14
|
t.pattern = ENV['PATTERN'] || 'test/*_test.rb'
|
9
|
-
t.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
desc 'Run rubocop'
|
14
|
-
task :rubocop do
|
15
|
-
unless RUBY_VERSION < '1.9'
|
16
|
-
sh('rubocop --format simple') { |ok, _| ok || abort }
|
15
|
+
t.options = ''.tap do |o|
|
16
|
+
o << "--seed #{ENV['SEED']} " if ENV['SEED']
|
17
|
+
o << '--verbose ' if ENV['VERBOSE']
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
-
require 'rdoc/task'
|
22
|
-
|
23
|
-
Rake::RDocTask.new do |rd|
|
24
|
-
rd.main = 'README.md'
|
25
|
-
rd.rdoc_files.include('README.md', 'lib/**/*.rb')
|
26
|
-
rd.rdoc_dir = 'doc'
|
27
|
-
end
|
28
|
-
rescue LoadError
|
29
|
-
end
|
21
|
+
YARD::Rake::YardocTask.new
|
data/Vagrantfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# vim:filetype=ruby
|
2
|
+
|
3
|
+
Vagrant.configure('2') do |config|
|
4
|
+
config.vm.hostname = 'resque-scheduler'
|
5
|
+
config.vm.box = 'precise64'
|
6
|
+
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/precise/' <<
|
7
|
+
'current/precise-server-cloudimg-amd64-vagrant-disk1.box'
|
8
|
+
|
9
|
+
config.vm.network :private_network, ip: '33.33.33.10', auto_correct: true
|
10
|
+
config.vm.network :forwarded_port, guest: 5678, host: 15678,
|
11
|
+
auto_correct: true
|
12
|
+
|
13
|
+
config.vm.provision :shell, path: '.vagrant-provision.sh'
|
14
|
+
end
|
data/bin/resque-scheduler
CHANGED
data/examples/Rakefile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# vim:fileencoding=utf-8
|
2
|
-
require '
|
2
|
+
require 'resque/scheduler/tasks'
|
@@ -7,8 +7,8 @@ require 'resque'
|
|
7
7
|
redis_env_var = ENV['REDIS_PROVIDER'] || 'REDIS_URL'
|
8
8
|
Resque.redis = ENV[redis_env_var] || 'localhost:6379'
|
9
9
|
|
10
|
-
require '
|
11
|
-
require '
|
10
|
+
require 'resque-scheduler'
|
11
|
+
require 'resque/scheduler/server'
|
12
12
|
|
13
13
|
schedule_yml = ENV['RESQUE_SCHEDULE_YML']
|
14
14
|
if schedule_yml
|
@@ -33,11 +33,9 @@ class FixSchedulesJob
|
|
33
33
|
|
34
34
|
User.all.each do |user|
|
35
35
|
# get schedule for the user
|
36
|
-
schedule = Resque.
|
36
|
+
schedule = Resque.fetch_schedule("send_email_#{user.id}")
|
37
37
|
# if a user has no schedule, add it to the array
|
38
|
-
if schedule.nil?
|
39
|
-
users_unscheduled << user
|
40
|
-
end
|
38
|
+
users_unscheduled << user if schedule.nil?
|
41
39
|
end
|
42
40
|
|
43
41
|
if users_unscheduled.length > 0
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim:fileencoding=utf-8
|
2
2
|
|
3
3
|
require 'resque/tasks'
|
4
|
-
require '
|
4
|
+
require 'resque/scheduler/tasks'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
namespace :resque do
|
8
8
|
task :setup do
|
9
9
|
require 'resque'
|
10
|
-
require '
|
10
|
+
require 'resque-scheduler'
|
11
11
|
|
12
12
|
rails_root = ENV['RAILS_ROOT'] || File.expand_path('../../../', __FILE__)
|
13
13
|
rails_env = ENV['RAILS_ENV'] || 'development'
|
data/lib/resque-scheduler.rb
CHANGED
data/lib/resque/scheduler.rb
CHANGED
@@ -1,103 +1,33 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
2
|
+
|
1
3
|
require 'rufus/scheduler'
|
2
|
-
|
3
|
-
|
4
|
+
require_relative 'scheduler/configuration'
|
5
|
+
require_relative 'scheduler/locking'
|
6
|
+
require_relative 'scheduler/logger_builder'
|
7
|
+
require_relative 'scheduler/signal_handling'
|
4
8
|
|
5
9
|
module Resque
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def configure
|
12
|
-
yield self
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_writer :signal_queue
|
16
|
-
|
17
|
-
def signal_queue
|
18
|
-
@signal_queue ||= []
|
19
|
-
end
|
20
|
-
|
21
|
-
# Used in `#load_schedule_job`
|
22
|
-
attr_writer :env
|
23
|
-
|
24
|
-
def env
|
25
|
-
return @env if @env
|
26
|
-
@env ||= Rails.env if defined?(Rails)
|
27
|
-
@env ||= ENV['RAILS_ENV']
|
28
|
-
@env
|
29
|
-
end
|
30
|
-
|
31
|
-
# If true, logs more stuff...
|
32
|
-
attr_writer :verbose
|
33
|
-
|
34
|
-
def verbose
|
35
|
-
@verbose ||= !!ENV['VERBOSE']
|
36
|
-
end
|
37
|
-
|
38
|
-
# If set, produces no output
|
39
|
-
attr_writer :mute
|
40
|
-
|
41
|
-
def mute
|
42
|
-
@mute ||= !!ENV['MUTE']
|
43
|
-
end
|
44
|
-
|
45
|
-
# If set, will write messages to the file
|
46
|
-
attr_writer :logfile
|
47
|
-
|
48
|
-
def logfile
|
49
|
-
@logfile ||= ENV['LOGFILE']
|
50
|
-
end
|
51
|
-
|
52
|
-
# Sets whether to log in 'text' or 'json'
|
53
|
-
attr_writer :logformat
|
54
|
-
|
55
|
-
def logformat
|
56
|
-
@logformat ||= ENV['LOGFORMAT']
|
57
|
-
end
|
58
|
-
|
59
|
-
# If set, will try to update the schedule in the loop
|
60
|
-
attr_writer :dynamic
|
10
|
+
module Scheduler
|
11
|
+
autoload :Cli, 'resque/scheduler/cli'
|
12
|
+
autoload :Extension, 'resque/scheduler/extension'
|
13
|
+
autoload :Util, 'resque/scheduler/util'
|
14
|
+
autoload :VERSION, 'resque/scheduler/version'
|
61
15
|
|
62
|
-
|
63
|
-
@dynamic ||= !!ENV['DYNAMIC_SCHEDULE']
|
64
|
-
end
|
65
|
-
|
66
|
-
# If set, will append the app name to procline
|
67
|
-
attr_writer :app_name
|
68
|
-
|
69
|
-
def app_name
|
70
|
-
@app_name ||= ENV['APP_NAME']
|
71
|
-
end
|
72
|
-
|
73
|
-
# Amount of time in seconds to sleep between polls of the delayed
|
74
|
-
# queue. Defaults to 5
|
75
|
-
attr_writer :poll_sleep_amount
|
76
|
-
|
77
|
-
def poll_sleep_amount
|
78
|
-
@poll_sleep_amount ||=
|
79
|
-
Float(ENV.fetch('RESQUE_SCHEDULER_INTERVAL', '5'))
|
80
|
-
end
|
16
|
+
private
|
81
17
|
|
82
|
-
|
18
|
+
extend Resque::Scheduler::Locking
|
19
|
+
extend Resque::Scheduler::Configuration
|
20
|
+
extend Resque::Scheduler::SignalHandling
|
83
21
|
|
84
|
-
|
85
|
-
@logger ||= ResqueScheduler::LoggerBuilder.new(
|
86
|
-
:mute => mute,
|
87
|
-
:verbose => verbose,
|
88
|
-
:log_dev => logfile,
|
89
|
-
:format => logformat
|
90
|
-
).build
|
91
|
-
end
|
22
|
+
public
|
92
23
|
|
24
|
+
class << self
|
93
25
|
# the Rufus::Scheduler jobs that are scheduled
|
94
|
-
|
95
|
-
@@scheduled_jobs
|
96
|
-
end
|
26
|
+
attr_reader :scheduled_jobs
|
97
27
|
|
98
28
|
# Schedule all jobs and continually look for delayed jobs (never returns)
|
99
29
|
def run
|
100
|
-
|
30
|
+
procline 'Starting'
|
101
31
|
|
102
32
|
# trap signals
|
103
33
|
register_signal_handlers
|
@@ -121,7 +51,7 @@ module Resque
|
|
121
51
|
|
122
52
|
# Now start the scheduling part of the loop.
|
123
53
|
loop do
|
124
|
-
if
|
54
|
+
if master?
|
125
55
|
begin
|
126
56
|
handle_delayed_items
|
127
57
|
update_schedule if dynamic
|
@@ -137,33 +67,11 @@ module Resque
|
|
137
67
|
end
|
138
68
|
end
|
139
69
|
|
140
|
-
# For all signals, set the shutdown flag and wait for current
|
141
|
-
# poll/enqueing to finish (should be almost instant). In the
|
142
|
-
# case of sleeping, exit immediately.
|
143
|
-
def register_signal_handlers
|
144
|
-
%w(INT TERM USR1 USR2 QUIT).each do |sig|
|
145
|
-
trap(sig) { signal_queue << sig }
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def handle_signals
|
150
|
-
loop do
|
151
|
-
sig = signal_queue.shift
|
152
|
-
break unless sig
|
153
|
-
log! "Got #{sig} signal"
|
154
|
-
case sig
|
155
|
-
when 'INT', 'TERM', 'QUIT' then shutdown
|
156
|
-
when 'USR1' then print_schedule
|
157
|
-
when 'USR2' then reload_schedule!
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
70
|
def print_schedule
|
163
71
|
if rufus_scheduler
|
164
72
|
log! "Scheduling Info\tLast Run"
|
165
73
|
scheduler_jobs = rufus_scheduler.all_jobs
|
166
|
-
scheduler_jobs.each do |
|
74
|
+
scheduler_jobs.each do |_k, v|
|
167
75
|
log! "#{v.t}\t#{v.last}\t"
|
168
76
|
end
|
169
77
|
end
|
@@ -172,20 +80,20 @@ module Resque
|
|
172
80
|
# Pulls the schedule from Resque.schedule and loads it into the
|
173
81
|
# rufus scheduler instance
|
174
82
|
def load_schedule!
|
175
|
-
procline
|
83
|
+
procline 'Loading Schedule'
|
176
84
|
|
177
85
|
# Need to load the schedule from redis for the first time if dynamic
|
178
86
|
Resque.reload_schedule! if dynamic
|
179
87
|
|
180
|
-
log!
|
88
|
+
log! 'Schedule empty! Set Resque.schedule' if Resque.schedule.empty?
|
181
89
|
|
182
|
-
|
90
|
+
@scheduled_jobs = {}
|
183
91
|
|
184
92
|
Resque.schedule.each do |name, config|
|
185
93
|
load_schedule_job(name, config)
|
186
94
|
end
|
187
95
|
Resque.redis.del(:schedules_changed)
|
188
|
-
procline
|
96
|
+
procline 'Schedules Loaded'
|
189
97
|
end
|
190
98
|
|
191
99
|
# modify interval type value to value with options if options available
|
@@ -194,17 +102,17 @@ module Resque
|
|
194
102
|
if args.is_a?(::Array)
|
195
103
|
return args.first if args.size > 2 || !args.last.is_a?(::Hash)
|
196
104
|
# symbolize keys of hash for options
|
197
|
-
args[1] = args[1].
|
105
|
+
args[1] = args[1].reduce({}) do |m, i|
|
198
106
|
key, value = i
|
199
|
-
m[(key.to_sym
|
107
|
+
m[(key.respond_to?(:to_sym) ? key.to_sym : key) || key] = value
|
200
108
|
m
|
201
109
|
end
|
202
110
|
end
|
203
111
|
args
|
204
112
|
end
|
205
113
|
|
206
|
-
# Loads a job schedule into the Rufus::Scheduler and stores it
|
207
|
-
#
|
114
|
+
# Loads a job schedule into the Rufus::Scheduler and stores it
|
115
|
+
# in @scheduled_jobs
|
208
116
|
def load_schedule_job(name, config)
|
209
117
|
# If `rails_env` or `env` is set in the config, load jobs only if they
|
210
118
|
# are meant to be loaded in `Resque::Scheduler.env`. If `rails_env` or
|
@@ -216,33 +124,36 @@ module Resque
|
|
216
124
|
if configured_env.nil? || env_matches?(configured_env)
|
217
125
|
log! "Scheduling #{name} "
|
218
126
|
interval_defined = false
|
219
|
-
interval_types = %w
|
127
|
+
interval_types = %w(cron every)
|
220
128
|
interval_types.each do |interval_type|
|
221
129
|
if !config[interval_type].nil? && config[interval_type].length > 0
|
222
130
|
args = optionizate_interval_value(config[interval_type])
|
223
|
-
|
224
|
-
if
|
131
|
+
job = rufus_scheduler.send(interval_type, *args) do
|
132
|
+
if master?
|
225
133
|
log! "queueing #{config['class']} (#{name})"
|
134
|
+
Resque.last_enqueued_at(name, Time.now.to_s)
|
226
135
|
handle_errors { enqueue_from_config(config) }
|
227
136
|
end
|
228
137
|
end
|
138
|
+
@scheduled_jobs[name] = job
|
229
139
|
interval_defined = true
|
230
140
|
break
|
231
141
|
end
|
232
142
|
end
|
233
143
|
unless interval_defined
|
234
|
-
log! "no #{interval_types.join(' / ')} found for
|
144
|
+
log! "no #{interval_types.join(' / ')} found for " \
|
145
|
+
"#{config['class']} (#{name}) - skipping"
|
235
146
|
end
|
236
147
|
else
|
237
|
-
log "Skipping schedule of #{name} because configured "
|
238
|
-
"env #{configured_env.inspect} does not match current "
|
148
|
+
log "Skipping schedule of #{name} because configured " \
|
149
|
+
"env #{configured_env.inspect} does not match current " \
|
239
150
|
"env #{env.inspect}"
|
240
151
|
end
|
241
152
|
end
|
242
153
|
|
243
154
|
# Returns true if the given schedule config hash matches the current env
|
244
155
|
def rails_env_matches?(config)
|
245
|
-
warn '`Resque::Scheduler.rails_env_matches?` is deprecated. '
|
156
|
+
warn '`Resque::Scheduler.rails_env_matches?` is deprecated. ' \
|
246
157
|
'Please use `Resque::Scheduler.env_matches?` instead.'
|
247
158
|
config['rails_env'] && env &&
|
248
159
|
config['rails_env'].split(/[\s,]+/).include?(env)
|
@@ -256,10 +167,11 @@ module Resque
|
|
256
167
|
|
257
168
|
# Handles queueing delayed items
|
258
169
|
# at_time - Time to start scheduling items (default: now).
|
259
|
-
def handle_delayed_items(at_time=nil)
|
260
|
-
|
261
|
-
|
262
|
-
|
170
|
+
def handle_delayed_items(at_time = nil)
|
171
|
+
timestamp = Resque.next_delayed_timestamp(at_time)
|
172
|
+
if timestamp
|
173
|
+
procline 'Processing Delayed Items'
|
174
|
+
until timestamp.nil?
|
263
175
|
enqueue_delayed_items_for_timestamp(timestamp)
|
264
176
|
timestamp = Resque.next_delayed_timestamp(at_time)
|
265
177
|
end
|
@@ -269,16 +181,21 @@ module Resque
|
|
269
181
|
# Enqueues all delayed jobs for a timestamp
|
270
182
|
def enqueue_delayed_items_for_timestamp(timestamp)
|
271
183
|
item = nil
|
272
|
-
|
184
|
+
loop do
|
273
185
|
handle_shutdown do
|
274
186
|
# Continually check that it is still the master
|
275
|
-
if
|
276
|
-
|
277
|
-
|
187
|
+
if master?
|
188
|
+
item = Resque.next_item_for_timestamp(timestamp)
|
189
|
+
if item
|
190
|
+
log "queuing #{item['class']} [delayed]"
|
191
|
+
handle_errors { enqueue_from_config(item) }
|
192
|
+
end
|
278
193
|
end
|
279
194
|
end
|
280
|
-
|
281
|
-
|
195
|
+
# continue processing until there are no more ready items in this
|
196
|
+
# timestamp
|
197
|
+
break if item.nil?
|
198
|
+
end
|
282
199
|
end
|
283
200
|
|
284
201
|
def handle_shutdown
|
@@ -288,11 +205,9 @@ module Resque
|
|
288
205
|
end
|
289
206
|
|
290
207
|
def handle_errors
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
log_error "#{e.class.name}: #{e.message}"
|
295
|
-
end
|
208
|
+
yield
|
209
|
+
rescue Exception => e
|
210
|
+
log_error "#{e.class.name}: #{e.message}"
|
296
211
|
end
|
297
212
|
|
298
213
|
# Enqueues a job based on a config hash
|
@@ -300,30 +215,45 @@ module Resque
|
|
300
215
|
args = job_config['args'] || job_config[:args]
|
301
216
|
|
302
217
|
klass_name = job_config['class'] || job_config[:class]
|
303
|
-
|
218
|
+
begin
|
219
|
+
klass = Resque::Scheduler::Util.constantize(klass_name)
|
220
|
+
rescue NameError
|
221
|
+
klass = klass_name
|
222
|
+
end
|
304
223
|
|
305
224
|
params = args.is_a?(Hash) ? [args] : Array(args)
|
306
|
-
queue = job_config['queue'] ||
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
225
|
+
queue = job_config['queue'] ||
|
226
|
+
job_config[:queue] ||
|
227
|
+
Resque.queue_from_class(klass)
|
228
|
+
# Support custom job classes like those that inherit from
|
229
|
+
# Resque::JobWithStatus (resque-status)
|
230
|
+
job_klass = job_config['custom_job_class']
|
231
|
+
if job_klass && job_klass != 'Resque::Job'
|
232
|
+
# The custom job class API must offer a static "scheduled" method. If
|
233
|
+
# the custom job class can not be constantized (via a requeue call
|
234
|
+
# from the web perhaps), fall back to enqueing normally via
|
235
|
+
# Resque::Job.create.
|
312
236
|
begin
|
313
|
-
|
237
|
+
Resque::Scheduler::Util.constantize(job_klass).scheduled(
|
238
|
+
queue, klass_name, *params
|
239
|
+
)
|
314
240
|
rescue NameError
|
315
|
-
# Note that the custom job class (job_config['custom_job_class'])
|
241
|
+
# Note that the custom job class (job_config['custom_job_class'])
|
242
|
+
# is the one enqueued
|
316
243
|
Resque::Job.create(queue, job_klass, *params)
|
317
244
|
end
|
318
245
|
else
|
319
|
-
#
|
246
|
+
# Hack to avoid havoc for people shoving stuff into queues
|
320
247
|
# for non-existent classes (for example: running scheduler in
|
321
|
-
# one app that schedules for another
|
248
|
+
# one app that schedules for another.
|
322
249
|
if Class === klass
|
323
|
-
|
250
|
+
Resque::Scheduler::Plugin.run_before_delayed_enqueue_hooks(
|
251
|
+
klass, *params
|
252
|
+
)
|
324
253
|
|
325
|
-
# If the class is a custom job class, call self#scheduled on it.
|
326
|
-
#
|
254
|
+
# If the class is a custom job class, call self#scheduled on it.
|
255
|
+
# This allows you to do things like Resque.enqueue_at(timestamp,
|
256
|
+
# CustomJobClass). Otherwise, pass off to Resque.
|
327
257
|
if klass.respond_to?(:scheduled)
|
328
258
|
klass.scheduled(queue, klass_name, *params)
|
329
259
|
else
|
@@ -346,29 +276,30 @@ module Resque
|
|
346
276
|
def clear_schedule!
|
347
277
|
rufus_scheduler.stop
|
348
278
|
@rufus_scheduler = nil
|
349
|
-
|
279
|
+
@scheduled_jobs = {}
|
350
280
|
rufus_scheduler
|
351
281
|
end
|
352
282
|
|
353
283
|
def reload_schedule!
|
354
|
-
procline
|
284
|
+
procline 'Reloading Schedule'
|
355
285
|
clear_schedule!
|
356
286
|
load_schedule!
|
357
287
|
end
|
358
288
|
|
359
289
|
def update_schedule
|
360
290
|
if Resque.redis.scard(:schedules_changed) > 0
|
361
|
-
procline
|
362
|
-
|
363
|
-
|
364
|
-
|
291
|
+
procline 'Updating schedule'
|
292
|
+
loop do
|
293
|
+
schedule_name = Resque.redis.spop(:schedules_changed)
|
294
|
+
break unless schedule_name
|
295
|
+
if Resque.reload_schedule!.keys.include?(schedule_name)
|
365
296
|
unschedule_job(schedule_name)
|
366
297
|
load_schedule_job(schedule_name, Resque.schedule[schedule_name])
|
367
298
|
else
|
368
299
|
unschedule_job(schedule_name)
|
369
300
|
end
|
370
301
|
end
|
371
|
-
procline
|
302
|
+
procline 'Schedules Loaded'
|
372
303
|
end
|
373
304
|
end
|
374
305
|
|
@@ -376,7 +307,7 @@ module Resque
|
|
376
307
|
if scheduled_jobs[name]
|
377
308
|
log "Removing schedule #{name}"
|
378
309
|
scheduled_jobs[name].unschedule
|
379
|
-
|
310
|
+
@scheduled_jobs.delete(name)
|
380
311
|
end
|
381
312
|
end
|
382
313
|
|
@@ -396,9 +327,11 @@ module Resque
|
|
396
327
|
@sleeping = true
|
397
328
|
start = Time.now
|
398
329
|
loop do
|
399
|
-
|
330
|
+
elapsed_sleep = (Time.now - start)
|
331
|
+
remaining_sleep = poll_sleep_amount - elapsed_sleep
|
332
|
+
break if remaining_sleep <= 0
|
400
333
|
begin
|
401
|
-
sleep
|
334
|
+
sleep(remaining_sleep)
|
402
335
|
handle_signals
|
403
336
|
rescue Interrupt
|
404
337
|
if @shutdown
|
@@ -439,6 +372,17 @@ module Resque
|
|
439
372
|
|
440
373
|
private
|
441
374
|
|
375
|
+
attr_writer :logger
|
376
|
+
|
377
|
+
def logger
|
378
|
+
@logger ||= Resque::Scheduler::LoggerBuilder.new(
|
379
|
+
quiet: quiet,
|
380
|
+
verbose: verbose,
|
381
|
+
log_dev: logfile,
|
382
|
+
format: logformat
|
383
|
+
).build
|
384
|
+
end
|
385
|
+
|
442
386
|
def app_str
|
443
387
|
app_name ? "[#{app_name}]" : ''
|
444
388
|
end
|
@@ -452,7 +396,7 @@ module Resque
|
|
452
396
|
end
|
453
397
|
|
454
398
|
def internal_name
|
455
|
-
"resque-scheduler-#{
|
399
|
+
"resque-scheduler-#{Resque::Scheduler::VERSION}"
|
456
400
|
end
|
457
401
|
end
|
458
402
|
end
|