resque-scheduler 2.5.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
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
|