resque-mongo-scheduler 2.0.2
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.
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +47 -0
- data/HISTORY.md +88 -0
- data/LICENSE +21 -0
- data/README.markdown +316 -0
- data/Rakefile +13 -0
- data/lib/resque/scheduler.rb +244 -0
- data/lib/resque_scheduler/search_delayed.rb +49 -0
- data/lib/resque_scheduler/server/views/delayed.erb +64 -0
- data/lib/resque_scheduler/server/views/delayed_timestamp.erb +26 -0
- data/lib/resque_scheduler/server/views/scheduler.erb +39 -0
- data/lib/resque_scheduler/server.rb +58 -0
- data/lib/resque_scheduler/tasks.rb +25 -0
- data/lib/resque_scheduler/version.rb +3 -0
- data/lib/resque_scheduler.rb +238 -0
- data/resque-mongo-scheduler.gemspec +29 -0
- data/tasks/resque_scheduler.rake +2 -0
- data/test/delayed_queue_test.rb +234 -0
- data/test/redis-test.conf +115 -0
- data/test/resque-web_test.rb +31 -0
- data/test/scheduler_args_test.rb +83 -0
- data/test/scheduler_test.rb +241 -0
- data/test/test_helper.rb +92 -0
- metadata +150 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'rufus/scheduler'
|
2
|
+
require 'thwait'
|
3
|
+
|
4
|
+
module Resque
|
5
|
+
|
6
|
+
class Scheduler
|
7
|
+
|
8
|
+
extend Resque::Helpers
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# If true, logs more stuff...
|
13
|
+
attr_accessor :verbose
|
14
|
+
|
15
|
+
# If set, produces no output
|
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
|
25
|
+
|
26
|
+
# Schedule all jobs and continually look for delayed jobs (never returns)
|
27
|
+
def run
|
28
|
+
$0 = "resque-mongo-scheduler: Starting"
|
29
|
+
# trap signals
|
30
|
+
register_signal_handlers
|
31
|
+
|
32
|
+
# Load the schedule into rufus
|
33
|
+
procline "Loading Schedule"
|
34
|
+
load_schedule!
|
35
|
+
|
36
|
+
# Now start the scheduling part of the loop.
|
37
|
+
loop do
|
38
|
+
handle_delayed_items
|
39
|
+
update_schedule if dynamic
|
40
|
+
poll_sleep
|
41
|
+
end
|
42
|
+
|
43
|
+
# never gets here.
|
44
|
+
end
|
45
|
+
|
46
|
+
# For all signals, set the shutdown flag and wait for current
|
47
|
+
# poll/enqueing to finish (should be almost istant). In the
|
48
|
+
# case of sleeping, exit immediately.
|
49
|
+
def register_signal_handlers
|
50
|
+
trap("TERM") { shutdown }
|
51
|
+
trap("INT") { shutdown }
|
52
|
+
|
53
|
+
begin
|
54
|
+
trap('QUIT') { shutdown }
|
55
|
+
trap('USR1') { kill_child }
|
56
|
+
trap('USR2') { reload_schedule! }
|
57
|
+
rescue ArgumentError
|
58
|
+
warn "Signals QUIT and USR1 and USR2 not supported."
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Pulls the schedule from Resque.schedule and loads it into the
|
63
|
+
# rufus scheduler instance
|
64
|
+
def load_schedule!
|
65
|
+
log! "Schedule empty! Set Resque.schedule" if Resque.schedule.empty?
|
66
|
+
|
67
|
+
@@scheduled_jobs = {}
|
68
|
+
|
69
|
+
Resque.schedule.each do |name, config|
|
70
|
+
load_schedule_job(name, config)
|
71
|
+
end
|
72
|
+
Resque.schedules_changed.remove
|
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
|
90
|
+
log! "queueing #{config['class']} (#{name})"
|
91
|
+
enqueue_from_config(config)
|
92
|
+
end
|
93
|
+
rescue Exception => e
|
94
|
+
log! "#{e.class.name}: #{e.message}"
|
95
|
+
end
|
96
|
+
interval_defined = true
|
97
|
+
break
|
98
|
+
end
|
99
|
+
end
|
100
|
+
unless interval_defined
|
101
|
+
log! "no #{interval_types.join(' / ')} found for #{config['class']} (#{name}) - skipping"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns true if the given schedule config hash matches the current
|
107
|
+
# ENV['RAILS_ENV']
|
108
|
+
def rails_env_matches?(config)
|
109
|
+
config['rails_env'] && ENV['RAILS_ENV'] && config['rails_env'].gsub(/\s/,'').split(',').include?(ENV['RAILS_ENV'])
|
110
|
+
end
|
111
|
+
|
112
|
+
# Handles queueing delayed items
|
113
|
+
# at_time - Time to start scheduling items (default: now).
|
114
|
+
def handle_delayed_items(at_time=nil)
|
115
|
+
item = nil
|
116
|
+
if timestamp = Resque.next_delayed_timestamp(at_time)
|
117
|
+
procline "Processing Delayed Items"
|
118
|
+
while !timestamp.nil?
|
119
|
+
enqueue_delayed_items_for_timestamp(timestamp)
|
120
|
+
timestamp = Resque.next_delayed_timestamp(at_time)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Enqueues all delayed jobs for a timestamp
|
126
|
+
def enqueue_delayed_items_for_timestamp(timestamp)
|
127
|
+
item = nil
|
128
|
+
begin
|
129
|
+
handle_shutdown do
|
130
|
+
if item = Resque.next_item_for_timestamp(timestamp)
|
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
|
+
klass, args = item['class'], item['args']
|
139
|
+
Resque.enqueue(constantize(klass), *args)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
# continue processing until there are no more ready items in this timestamp
|
144
|
+
end while !item.nil?
|
145
|
+
end
|
146
|
+
|
147
|
+
def handle_shutdown
|
148
|
+
exit if @shutdown
|
149
|
+
yield
|
150
|
+
exit if @shutdown
|
151
|
+
end
|
152
|
+
|
153
|
+
# Enqueues a job based on a config hash
|
154
|
+
def enqueue_from_config(config)
|
155
|
+
args = config['args'] || config[:args]
|
156
|
+
klass_name = config['class'] || config[:class]
|
157
|
+
params = args.is_a?(Hash) ? [args] : Array(args)
|
158
|
+
queue = config['queue'] || config[:queue] || Resque.queue_from_class(constantize(klass_name))
|
159
|
+
# Support custom job classes like job with status
|
160
|
+
if (job_klass = config['custom_job_class']) && (job_klass != 'Resque::Job')
|
161
|
+
# custom job classes not supporting the same API calls must implement the #schedule method
|
162
|
+
constantize(job_klass).scheduled(queue, klass_name, *params)
|
163
|
+
else
|
164
|
+
Resque.enqueue(constantize(klass_name), *params)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def rufus_scheduler
|
169
|
+
@rufus_scheduler ||= Rufus::Scheduler.start_new
|
170
|
+
end
|
171
|
+
|
172
|
+
# Stops old rufus scheduler and creates a new one. Returns the new
|
173
|
+
# rufus scheduler
|
174
|
+
def clear_schedule!
|
175
|
+
rufus_scheduler.stop
|
176
|
+
@rufus_scheduler = nil
|
177
|
+
@@scheduled_jobs = {}
|
178
|
+
rufus_scheduler
|
179
|
+
end
|
180
|
+
|
181
|
+
def reload_schedule!
|
182
|
+
procline "Reloading Schedule"
|
183
|
+
clear_schedule!
|
184
|
+
Resque.reload_schedule!
|
185
|
+
load_schedule!
|
186
|
+
end
|
187
|
+
|
188
|
+
def update_schedule
|
189
|
+
if Resque.schedules_changed.count > 0
|
190
|
+
procline "Updating schedule"
|
191
|
+
Resque.reload_schedule!
|
192
|
+
Resque.pop_schedules_changed do |schedule_name|
|
193
|
+
if Resque.schedule.keys.include?(schedule_name)
|
194
|
+
unschedule_job(schedule_name)
|
195
|
+
load_schedule_job(schedule_name, Resque.schedule[schedule_name])
|
196
|
+
else
|
197
|
+
unschedule_job(schedule_name)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
procline "Schedules Loaded"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def unschedule_job(name)
|
205
|
+
if scheduled_jobs[name]
|
206
|
+
log "Removing schedule #{name}"
|
207
|
+
scheduled_jobs[name].unschedule
|
208
|
+
@@scheduled_jobs.delete(name)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Sleeps and returns true
|
213
|
+
def poll_sleep
|
214
|
+
@sleeping = true
|
215
|
+
handle_shutdown { sleep 5 }
|
216
|
+
@sleeping = false
|
217
|
+
true
|
218
|
+
end
|
219
|
+
|
220
|
+
# Sets the shutdown flag, exits if sleeping
|
221
|
+
def shutdown
|
222
|
+
@shutdown = true
|
223
|
+
exit if @sleeping
|
224
|
+
end
|
225
|
+
|
226
|
+
def log!(msg)
|
227
|
+
puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} #{msg}" unless mute
|
228
|
+
end
|
229
|
+
|
230
|
+
def log(msg)
|
231
|
+
# add "verbose" logic later
|
232
|
+
log!(msg) if verbose
|
233
|
+
end
|
234
|
+
|
235
|
+
def procline(string)
|
236
|
+
$0 = "resque-mongo-scheduler-#{ResqueScheduler::Version}: #{string}"
|
237
|
+
log! $0
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ResqueScheduler
|
2
|
+
|
3
|
+
def search_delayed_count
|
4
|
+
@@search_results.count
|
5
|
+
end
|
6
|
+
|
7
|
+
def search_delayed(query, start = 0, count = 1)
|
8
|
+
if query.nil? || query.empty?
|
9
|
+
@@search_results = []
|
10
|
+
return []
|
11
|
+
end
|
12
|
+
|
13
|
+
start, count = [start, count].map { |n| Integer(n) }
|
14
|
+
set_results = Set.new
|
15
|
+
|
16
|
+
# For each search term, retrieve the failed jobs that contain at least one relevant field matching the regexp defined by that search term
|
17
|
+
query.split.each do |term|
|
18
|
+
|
19
|
+
partial_results = []
|
20
|
+
self.delayed_queue.find().each do |row|
|
21
|
+
row['items'].each do |job|
|
22
|
+
if job['class'] =~ /#{term}/i || job['queue'] =~ /#{term}/i
|
23
|
+
partial_results << row['_id']
|
24
|
+
else
|
25
|
+
job['args'].each do |arg|
|
26
|
+
arg.each do |key, value|
|
27
|
+
if key =~ /#{term}/i || value =~ /#{term}/i
|
28
|
+
partial_results << row['_id']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# If the set was empty, merge the first results, else intersect it with the current results
|
37
|
+
if set_results.empty?
|
38
|
+
set_results.merge(partial_results)
|
39
|
+
else
|
40
|
+
set_results = set_results & partial_results
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# search_res will be an array containing 'count' values, starting with 'start', sorted in descending order
|
45
|
+
@@search_results = set_results.to_a || []
|
46
|
+
search_results = set_results.to_a[start, count]
|
47
|
+
search_results || []
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<%start = params[:start].to_i %>
|
2
|
+
<%count = params[:count] ? params[:count].to_i : 50 %>
|
3
|
+
|
4
|
+
<%if params[:q].nil?%>
|
5
|
+
<% delayed = [resque.delayed_queue_peek(start, start + 20)].flatten %>
|
6
|
+
<% size = resque.delayed_queue_schedule_size %>
|
7
|
+
<h1>Delayed Jobs</h1>
|
8
|
+
<%else%>
|
9
|
+
<% delayed = [resque.search_delayed(params[:q], start, count)].flatten %>
|
10
|
+
<% size = resque.search_delayed_count %>
|
11
|
+
<h1>Delayed jobs search results</h1>
|
12
|
+
<%end%>
|
13
|
+
|
14
|
+
<p class='intro'>
|
15
|
+
This list below contains the timestamps for scheduled delayed jobs.
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<% unless size.zero? %>
|
19
|
+
<form method="GET" action="<%=u 'delayed'%>">
|
20
|
+
<input type='text' name='q'>
|
21
|
+
<input type='submit' name='' value='Search' />
|
22
|
+
</form>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<p class='sub'>
|
26
|
+
Showing <%= start %> to <%= start + delayed.size %> of <b><%= size %></b> timestamps
|
27
|
+
</p>
|
28
|
+
|
29
|
+
|
30
|
+
<table>
|
31
|
+
<tr>
|
32
|
+
<th></th>
|
33
|
+
<th>Timestamp</th>
|
34
|
+
<th>Job count</th>
|
35
|
+
<th>Class</th>
|
36
|
+
<th>Args</th>
|
37
|
+
<th>Queue</th>
|
38
|
+
</tr>
|
39
|
+
<% delayed.each do |timestamp| %>
|
40
|
+
<tr>
|
41
|
+
<td>
|
42
|
+
<form action="<%= url "/delayed/queue_now" %>" method="post" style="margin-top: 0px;">
|
43
|
+
<input type="hidden" name="timestamp" value="<%= timestamp.to_i %>">
|
44
|
+
<input type="submit" value="Queue now">
|
45
|
+
</form>
|
46
|
+
</td>
|
47
|
+
<td><a href="<%= url "delayed/#{timestamp}" %>"><%= format_time(Time.at(timestamp)) %></a></td>
|
48
|
+
<td><%= delayed_timestamp_size = resque.delayed_timestamp_size(timestamp) %></td>
|
49
|
+
<% job = resque.delayed_timestamp_peek(timestamp, 0, 1).first %>
|
50
|
+
<td>
|
51
|
+
<% if job && delayed_timestamp_size == 1 %>
|
52
|
+
<%= h(job['class']) %>
|
53
|
+
<% else %>
|
54
|
+
<a href="<%= url "delayed/#{timestamp}" %>">see details</a>
|
55
|
+
<% end %>
|
56
|
+
</td>
|
57
|
+
<td><%= h(job['args'].inspect) if job && delayed_timestamp_size == 1 %></td>
|
58
|
+
<td><%= h(job['queue'].inspect) if job && delayed_timestamp_size == 1 %></td>
|
59
|
+
</tr>
|
60
|
+
<% end %>
|
61
|
+
</table>
|
62
|
+
|
63
|
+
|
64
|
+
<%= partial :next_more, :start => start, :count => count, :size => size %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% timestamp = params[:timestamp].to_i %>
|
2
|
+
|
3
|
+
<h1>Delayed jobs scheduled for <%= format_time(Time.at(timestamp)) %></h1>
|
4
|
+
|
5
|
+
<p class='sub'>Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%=size = resque.delayed_timestamp_size(timestamp)%></b> jobs</p>
|
6
|
+
|
7
|
+
<table class='jobs'>
|
8
|
+
<tr>
|
9
|
+
<th>Class</th>
|
10
|
+
<th>Args</th>
|
11
|
+
</tr>
|
12
|
+
<% jobs = resque.delayed_timestamp_peek(timestamp, start, 20) %>
|
13
|
+
<% jobs.each do |job| %>
|
14
|
+
<tr>
|
15
|
+
<td class='class'><%= job['class'] %></td>
|
16
|
+
<td class='args'><%=h job['args'].inspect %></td>
|
17
|
+
</tr>
|
18
|
+
<% end %>
|
19
|
+
<% if jobs.empty? %>
|
20
|
+
<tr>
|
21
|
+
<td class='no-data' colspan='2'>There are no pending jobs scheduled for this time.</td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</table>
|
25
|
+
|
26
|
+
<%= partial :next_more, :start => start, :size => size %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<h1>Schedule</h1>
|
2
|
+
|
3
|
+
<p class='intro'>
|
4
|
+
The list below contains all scheduled jobs. Click "Queue now" to queue
|
5
|
+
a job immediately.
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<table>
|
9
|
+
<tr>
|
10
|
+
<th></th>
|
11
|
+
<th>Name</th>
|
12
|
+
<th>Description</th>
|
13
|
+
<th>Interval</th>
|
14
|
+
<th>Class</th>
|
15
|
+
<th>Queue</th>
|
16
|
+
<th>Arguments</th>
|
17
|
+
</tr>
|
18
|
+
<% Resque.schedule.keys.sort.each do |name| %>
|
19
|
+
<% config = Resque.schedule[name] %>
|
20
|
+
<tr>
|
21
|
+
<td>
|
22
|
+
<form action="<%= url "/schedule/requeue" %>" method="post">
|
23
|
+
<input type="hidden" name="job_name" value="<%= h name %>">
|
24
|
+
<input type="submit" value="Queue now">
|
25
|
+
</form>
|
26
|
+
</td>
|
27
|
+
<td><%= h name %></td>
|
28
|
+
<td><%= h config['description'] %></td>
|
29
|
+
<td style="white-space:nowrap"><%= (config['cron'].nil? && !config['every'].nil?) ?
|
30
|
+
h('every: ' + config['every']) :
|
31
|
+
h('cron: ' + config['cron']) %></td>
|
32
|
+
<td><%= (config['class'].nil? && !config['custom_job_class'].nil?) ?
|
33
|
+
h(config['custom_job_class']) :
|
34
|
+
h(config['class']) %></td>
|
35
|
+
<td><%= h config['queue'] || queue_from_class_name(config['class']) %></td>
|
36
|
+
<td><%= h config['args'].inspect %></td>
|
37
|
+
</tr>
|
38
|
+
<% end %>
|
39
|
+
</table>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
# Extend Resque::Server to add tabs
|
3
|
+
module ResqueScheduler
|
4
|
+
|
5
|
+
module Server
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
|
9
|
+
base.class_eval do
|
10
|
+
|
11
|
+
helpers do
|
12
|
+
def format_time(t)
|
13
|
+
t.strftime("%Y-%m-%d %H:%M:%S")
|
14
|
+
end
|
15
|
+
|
16
|
+
def queue_from_class_name(class_name)
|
17
|
+
Resque.queue_from_class(Resque.constantize(class_name))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
get "/schedule" do
|
22
|
+
Resque.reload_schedule! if Resque::Scheduler.dynamic
|
23
|
+
# Is there a better way to specify alternate template locations with sinatra?
|
24
|
+
erb File.read(File.join(File.dirname(__FILE__), 'server/views/scheduler.erb'))
|
25
|
+
end
|
26
|
+
|
27
|
+
post "/schedule/requeue" do
|
28
|
+
config = Resque.schedule[params['job_name']]
|
29
|
+
Resque::Scheduler.enqueue_from_config(config)
|
30
|
+
redirect url("/overview")
|
31
|
+
end
|
32
|
+
|
33
|
+
get "/delayed" do
|
34
|
+
# Is there a better way to specify alternate template locations with sinatra?
|
35
|
+
erb File.read(File.join(File.dirname(__FILE__), 'server/views/delayed.erb'))
|
36
|
+
end
|
37
|
+
|
38
|
+
get "/delayed/:timestamp" do
|
39
|
+
# Is there a better way to specify alternate template locations with sinatra?
|
40
|
+
erb File.read(File.join(File.dirname(__FILE__), 'server/views/delayed_timestamp.erb'))
|
41
|
+
end
|
42
|
+
|
43
|
+
post "/delayed/queue_now" do
|
44
|
+
timestamp = params['timestamp']
|
45
|
+
Resque::Scheduler.enqueue_delayed_items_for_timestamp(timestamp.to_i) if timestamp.to_i > 0
|
46
|
+
redirect url("/overview")
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
Resque::Server.tabs << 'Schedule'
|
54
|
+
Resque::Server.tabs << 'Delayed'
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# require 'resque/tasks'
|
2
|
+
# will give you the resque tasks
|
3
|
+
|
4
|
+
namespace :resque do
|
5
|
+
task :setup
|
6
|
+
|
7
|
+
desc "Start Resque Scheduler"
|
8
|
+
task :scheduler => :scheduler_setup do
|
9
|
+
gem 'resque-mongo'
|
10
|
+
require 'resque'
|
11
|
+
require 'resque_scheduler'
|
12
|
+
|
13
|
+
Resque::Scheduler.verbose = true if ENV['VERBOSE']
|
14
|
+
Resque::Scheduler.run
|
15
|
+
end
|
16
|
+
|
17
|
+
task :scheduler_setup do
|
18
|
+
if ENV['INITIALIZER_PATH']
|
19
|
+
load ENV['INITIALIZER_PATH'].to_s.strip
|
20
|
+
else
|
21
|
+
Rake::Task['resque:setup'].invoke
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|