resque_ui 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +3 -0
- data/History.txt +4 -0
- data/README.markdown +9 -5
- data/Rakefile +1 -1
- data/VERSION.yml +1 -1
- data/app/assets/stylesheets/resque_cleaner/cleaner.css +62 -0
- data/app/controllers/resque_controller.rb +167 -43
- data/app/helpers/resque_helper.rb +60 -27
- data/app/views/layouts/resque.html.erb +1 -0
- data/app/views/resque/_limiter.html.erb +12 -0
- data/app/views/resque/_paginate.html.erb +53 -0
- data/app/views/resque/_queues.html.erb +2 -2
- data/app/views/resque/_working.html.erb +1 -1
- data/app/views/resque/cleaner.html.erb +41 -0
- data/app/views/resque/cleaner_exec.html.erb +6 -0
- data/app/views/resque/cleaner_list.html.erb +172 -0
- data/app/views/resque/delayed_timestamp.html.erb +1 -1
- data/lib/resque_ui.rb +2 -1
- data/rdoc/Resque/ChainedJobWithStatus.html +0 -2
- data/rdoc/Resque/Job.html +0 -2
- data/rdoc/Resque/JobWithStatus.html +0 -2
- data/rdoc/Resque/Status.html +0 -2
- data/rdoc/Resque/Worker.html +0 -2
- data/rdoc/Resque.html +0 -7
- data/rdoc/ResqueScheduler.html +0 -2
- data/rdoc/ResqueUi/Cap.html +0 -2
- data/rdoc/ResqueUi/Engine.html +0 -2
- data/rdoc/ResqueUi.html +0 -2
- data/rdoc/created.rid +3 -4
- data/rdoc/index.html +3 -7
- data/rdoc/lib/resque_ui/cap_rb.html +1 -1
- data/rdoc/lib/resque_ui/cap_recipes_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque/job_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque/resque_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque/worker_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque_scheduler/resque_scheduler_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque_status/chained_job_with_status_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque_status/job_with_status_rb.html +1 -1
- data/rdoc/lib/resque_ui/overrides/resque_status/status_rb.html +1 -1
- data/rdoc/lib/resque_ui_rb.html +4 -4
- data/resque_ui.gemspec +12 -5
- metadata +20 -5
- data/app/views/resque/failed.html.erb +0 -54
- data/lib/resque_ui/overrides/resque/failure/failure.rb +0 -22
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -74,6 +74,8 @@ GEM
|
|
74
74
|
redis-namespace (~> 1.0.2)
|
75
75
|
sinatra (>= 0.9.2)
|
76
76
|
vegas (~> 0.1.2)
|
77
|
+
resque-cleaner (0.2.6)
|
78
|
+
resque (~> 1.0)
|
77
79
|
resque-status (0.2.3)
|
78
80
|
redisk (>= 0.2.1)
|
79
81
|
resque (>= 1.3.1)
|
@@ -99,4 +101,5 @@ DEPENDENCIES
|
|
99
101
|
rails (>= 3.0.0)
|
100
102
|
redis (>= 2.1.3)
|
101
103
|
resque (>= 1.5)
|
104
|
+
resque-cleaner (>= 0.2.6)
|
102
105
|
resque-status (>= 0.2.2)
|
data/History.txt
CHANGED
data/README.markdown
CHANGED
@@ -32,9 +32,11 @@ This engine now requires redis 2.1.3 or greater for the expiration of keys to wo
|
|
32
32
|
|
33
33
|
This engine requires the resque 1.5 or higher gem.
|
34
34
|
|
35
|
-
This engine now requires the resque-status 0.2.2 or higher gem
|
35
|
+
This engine now requires the resque-status 0.2.2 or higher gem.
|
36
36
|
|
37
|
-
|
37
|
+
This engine now requires the resque-cleaner 0.2.6 or higher gem.
|
38
|
+
|
39
|
+
These gems will all be installed for you automatically when you install resque_ui.
|
38
40
|
|
39
41
|
|
40
42
|
Times Fixed
|
@@ -67,9 +69,10 @@ This is really handy for those long running jobs to give you assurance the the j
|
|
67
69
|
Restart Failed Jobs
|
68
70
|
-------------------
|
69
71
|
|
70
|
-
Added the
|
72
|
+
Added the Resque Cleaner gem to manage the failed queue. Have complete control over the failed queue now with the
|
73
|
+
Cleaner tab by querying and restarting failed jobs.
|
71
74
|
|
72
|
-
|
75
|
+
See what all you can do on the github page: https://github.com/ono/resque-cleaner
|
73
76
|
|
74
77
|
Remove Items from the Queue
|
75
78
|
---------------------------
|
@@ -165,7 +168,7 @@ deployed servers.
|
|
165
168
|
|
166
169
|
The controller calls cap tasks to manage the workers. To include the recipes in your application, add this line to your deploy.rb file:
|
167
170
|
|
168
|
-
require
|
171
|
+
require 'resque_ui/cap_recipes'
|
169
172
|
|
170
173
|
You will also need to make sure you have your rake path set in the deploy.rb file.
|
171
174
|
|
@@ -272,6 +275,7 @@ time into resolving it.
|
|
272
275
|
Copyright (c) 2009 Chris Wanstrath
|
273
276
|
Copyright (c) 2010 Ben VandenBos
|
274
277
|
Copyright (c) 2010 Aaron Quint
|
278
|
+
Copyright (c) 2011 Tatsuya Ono
|
275
279
|
Copyright (c) 2010 Kevin Tyll, released under the MIT license
|
276
280
|
|
277
281
|
Thanks to Karl Baum for doing the original heavy lifting for converting this to a rails engine for rails 3.
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
gemspec.name = "resque_ui"
|
10
10
|
gemspec.author = "Kevin Tyll"
|
11
11
|
gemspec.email = "kevintyll@gmail.com"
|
12
|
-
gemspec.homepage = %q{
|
12
|
+
gemspec.homepage = %q{https://github.com/kevintyll/resque_ui}
|
13
13
|
gemspec.summary = "A Rails engine port of the Sinatra app that is included in Chris Wanstrath's resque gem."
|
14
14
|
gemspec.description = "A Rails UI for Resque for managing workers, failures and schedules."
|
15
15
|
end
|
data/VERSION.yml
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
#main .cleaner .title h1 { float: left }
|
2
|
+
|
3
|
+
#main .cleaner .sub_header {color: #888; font-size: 80%; font-weight: bold}
|
4
|
+
|
5
|
+
#main .cleaner .control_panel {
|
6
|
+
margin: 5px 0 10px; padding: 5px; background: #eee; display: inline-block;
|
7
|
+
-webkit-border-radius:5px; border:1px solid #ccc;
|
8
|
+
}
|
9
|
+
|
10
|
+
#main .cleaner #exec { color: black; }
|
11
|
+
#main .cleaner #exec select { margin-right: 20px }
|
12
|
+
#main .cleaner #exec a { margin-right: 5px}
|
13
|
+
#main .cleaner #exec a.disabled { color: #aaa}
|
14
|
+
|
15
|
+
#main .cleaner table.class_list { width: auto }
|
16
|
+
#main .cleaner td.number { text-align: right }
|
17
|
+
#main .cleaner tr.total { border-top: 3px double #ccc}
|
18
|
+
|
19
|
+
#main .cleaner form { float: none; margin: 0}
|
20
|
+
|
21
|
+
#main .cleaner .warning { margin: 30px 0; padding: 10px; background: #fdd; display: inline-block; }
|
22
|
+
|
23
|
+
#main .clearfix:after {
|
24
|
+
content: ".";
|
25
|
+
display: block;
|
26
|
+
height: 0;
|
27
|
+
clear: both;
|
28
|
+
visibility: hidden;
|
29
|
+
}
|
30
|
+
#main .cleaner ul.failed {
|
31
|
+
margin-bottom: 10px
|
32
|
+
}
|
33
|
+
|
34
|
+
#main .cleaner .list_info{
|
35
|
+
color: #999; text-align: center;
|
36
|
+
}
|
37
|
+
#main .cleaner .list_info a{
|
38
|
+
color: #666
|
39
|
+
}
|
40
|
+
#main .cleaner .list_info .list_summary{
|
41
|
+
vertical-align: baseline;
|
42
|
+
display: inline-block;
|
43
|
+
margin: 0; padding:0;
|
44
|
+
}
|
45
|
+
#main .cleaner ul.pagination {
|
46
|
+
display: inline-block;
|
47
|
+
vertical-align: baseline;
|
48
|
+
margin:0; padding:0;
|
49
|
+
}
|
50
|
+
#main .cleaner ul.pagination li {
|
51
|
+
list-style:none; float: left; padding: 0 3px;
|
52
|
+
}
|
53
|
+
#main .cleaner ul.pagination li.current {
|
54
|
+
color: #333; font-weight: bold;
|
55
|
+
}
|
56
|
+
#main .cleaner ul.pagination li.summary{
|
57
|
+
padding-right: 10px
|
58
|
+
}
|
59
|
+
#main .cleaner div.dump{
|
60
|
+
float: right
|
61
|
+
}
|
62
|
+
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'resque'
|
2
2
|
require 'resque/version'
|
3
|
+
require 'digest/sha1'
|
4
|
+
|
3
5
|
|
4
6
|
class ResqueController < ApplicationController
|
5
7
|
unloadable(self) #needed to prevent errors with authenticated system in dev env.
|
@@ -8,10 +10,12 @@ class ResqueController < ApplicationController
|
|
8
10
|
|
9
11
|
before_filter :check_connection
|
10
12
|
|
13
|
+
before_filter :get_cleaner, :only => [:cleaner, :cleaner_exec, :cleaner_list, :cleaner_stale, :cleaner_dump]
|
14
|
+
|
11
15
|
verify :method => :post, :only => [:clear_failures, :clear_failure, :requeue_failure, :stop_worker, :restart_worker,
|
12
16
|
:start_worker, :schedule_requeue, :remove_from_schedule, :add_scheduled_job,
|
13
17
|
:start_scheduler, :stop_scheduler, :requeue_failures_in_class,
|
14
|
-
:kill, :clear_statuses],
|
18
|
+
:kill, :clear_statuses, :cleaner_exec, :cleaner_stale],
|
15
19
|
:render => {:text => "<p>Please use the POST http method to post data to this API.</p>".html_safe}
|
16
20
|
|
17
21
|
|
@@ -43,36 +47,6 @@ class ResqueController < ApplicationController
|
|
43
47
|
render(:text => (render_to_string(:action => 'statuses.html', :layout => false)))
|
44
48
|
end
|
45
49
|
|
46
|
-
def failed
|
47
|
-
if Resque::Failure.url
|
48
|
-
redirect_to Resque::Failure.url
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def clear_failures
|
53
|
-
Resque::Failure.clear
|
54
|
-
redirect_to(:action => 'failed')
|
55
|
-
end
|
56
|
-
|
57
|
-
def clear_failure
|
58
|
-
remove_failure_from_list(Resque.decode(params[:payload]))
|
59
|
-
redirect_to(:action => 'failed')
|
60
|
-
end
|
61
|
-
|
62
|
-
def requeue_failure
|
63
|
-
#first clear the job we're restarting from the failure list.
|
64
|
-
payload = Resque.decode(params["payload"])
|
65
|
-
remove_failure_from_list(payload)
|
66
|
-
args = payload["args"]
|
67
|
-
Resque.enqueue(eval(payload["class"]), *args)
|
68
|
-
redirect_to(:action => 'failed')
|
69
|
-
end
|
70
|
-
|
71
|
-
def requeue_failures_in_class
|
72
|
-
Resque::Failure.requeue_class(params['class'])
|
73
|
-
redirect_to(:action => 'failed')
|
74
|
-
end
|
75
|
-
|
76
50
|
def remove_job
|
77
51
|
Resque.dequeue(params['class'].constantize, *Resque.decode(params['args']))
|
78
52
|
redirect_to request.referrer
|
@@ -118,6 +92,8 @@ class ResqueController < ApplicationController
|
|
118
92
|
end
|
119
93
|
end
|
120
94
|
|
95
|
+
# resque-scheduler actions
|
96
|
+
|
121
97
|
def schedule
|
122
98
|
@farm_status = ResqueScheduler.farm_status
|
123
99
|
end
|
@@ -176,6 +152,8 @@ class ResqueController < ApplicationController
|
|
176
152
|
redirect_to(:action => 'schedule')
|
177
153
|
end
|
178
154
|
|
155
|
+
# resque-status actions
|
156
|
+
|
179
157
|
def statuses
|
180
158
|
@start = params[:start].to_i
|
181
159
|
@end = @start + (params[:per_page] || 20)
|
@@ -206,6 +184,82 @@ class ResqueController < ApplicationController
|
|
206
184
|
redirect_to(:action => 'statuses')
|
207
185
|
end
|
208
186
|
|
187
|
+
def cleaner
|
188
|
+
load_cleaner_filter
|
189
|
+
|
190
|
+
@jobs = @cleaner.select
|
191
|
+
@stats, @total = {}, {"total" => 0, "1h" => 0, "3h" => 0, "1d" => 0, "3d" => 0, "7d" => 0}
|
192
|
+
@jobs.each do |job|
|
193
|
+
klass = job["payload"]["class"]
|
194
|
+
failed_at = Time.parse job["failed_at"]
|
195
|
+
|
196
|
+
@stats[klass] ||= {"total" => 0, "1h" => 0, "3h" => 0, "1d" => 0, "3d" => 0, "7d" => 0}
|
197
|
+
items = [@stats[klass], @total]
|
198
|
+
|
199
|
+
items.each { |a| a["total"] += 1 }
|
200
|
+
items.each { |a| a["1h"] += 1 } if failed_at >= hours_ago(1)
|
201
|
+
items.each { |a| a["3h"] += 1 } if failed_at >= hours_ago(3)
|
202
|
+
items.each { |a| a["1d"] += 1 } if failed_at >= hours_ago(24)
|
203
|
+
items.each { |a| a["3d"] += 1 } if failed_at >= hours_ago(24*3)
|
204
|
+
items.each { |a| a["7d"] += 1 } if failed_at >= hours_ago(24*7)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def cleaner_list
|
209
|
+
load_cleaner_filter
|
210
|
+
|
211
|
+
block = filter_block
|
212
|
+
|
213
|
+
@failed = @cleaner.select(&block).reverse
|
214
|
+
|
215
|
+
url = "cleaner_list?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
|
216
|
+
@dump_url = "cleaner_dump?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
|
217
|
+
@paginate = Paginate.new(@failed, url, params[:p].to_i)
|
218
|
+
|
219
|
+
@klasses = @cleaner.stats_by_class.keys
|
220
|
+
@exceptions = @cleaner.stats_by_exception.keys
|
221
|
+
@count = @cleaner.select(&block).size
|
222
|
+
end
|
223
|
+
|
224
|
+
def cleaner_exec
|
225
|
+
load_cleaner_filter
|
226
|
+
|
227
|
+
if params[:select_all_pages]!="1"
|
228
|
+
@sha1 = {}
|
229
|
+
params[:sha1].split(",").each { |s| @sha1[s] = true }
|
230
|
+
end
|
231
|
+
|
232
|
+
block = filter_block
|
233
|
+
|
234
|
+
@count =
|
235
|
+
case params[:form_action]
|
236
|
+
when "clear" then
|
237
|
+
@cleaner.clear(&block)
|
238
|
+
when "retry_and_clear" then
|
239
|
+
@cleaner.requeue(true, &block)
|
240
|
+
when "retry" then
|
241
|
+
@cleaner.requeue(false, {}, &block)
|
242
|
+
end
|
243
|
+
|
244
|
+
@link_url = "cleaner_list?c=#{@klass}&ex=#{@exception}&f=#{@from}&t=#{@to}"
|
245
|
+
end
|
246
|
+
|
247
|
+
def cleaner_dump
|
248
|
+
load_cleaner_filter
|
249
|
+
|
250
|
+
block = filter_block
|
251
|
+
failures = @cleaner.select(&block)
|
252
|
+
# pretty generate throws an error with the json gem on jruby
|
253
|
+
output = JSON.pretty_generate(failures) rescue failures.to_json
|
254
|
+
render :json => output
|
255
|
+
end
|
256
|
+
|
257
|
+
def cleaner_stale
|
258
|
+
@cleaner.clear_stale
|
259
|
+
redirect_to :action => "cleaner"
|
260
|
+
end
|
261
|
+
|
262
|
+
|
209
263
|
private
|
210
264
|
|
211
265
|
def check_connection
|
@@ -215,22 +269,92 @@ class ResqueController < ApplicationController
|
|
215
269
|
false
|
216
270
|
end
|
217
271
|
|
218
|
-
def remove_failure_from_list(payload)
|
219
|
-
count = Resque::Failure.count - 1
|
220
|
-
loop do
|
221
|
-
f = Resque::Failure.all(count, 1)
|
222
|
-
if f && f['payload'] == payload
|
223
|
-
Resque.redis.lrem(:failed, 0, f.to_json)
|
224
|
-
end
|
225
|
-
count = count - 1
|
226
|
-
break if count < 0
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
272
|
def find_worker(worker)
|
231
273
|
first_part, *rest = worker.split(':')
|
232
274
|
first_part.gsub!(/_/, '.')
|
233
275
|
Resque::Worker.find("#{first_part}:#{rest.join(':')}")
|
234
276
|
end
|
235
277
|
|
278
|
+
# resque-cleaner methods
|
279
|
+
|
280
|
+
def get_cleaner
|
281
|
+
@cleaner ||= Resque::Plugins::ResqueCleaner.new
|
282
|
+
@cleaner.print_message = false
|
283
|
+
@cleaner
|
284
|
+
end
|
285
|
+
|
286
|
+
def load_cleaner_filter
|
287
|
+
@from = params[:f]=="" ? nil : params[:f]
|
288
|
+
@to = params[:t]=="" ? nil : params[:t]
|
289
|
+
@klass = params[:c]=="" ? nil : params[:c]
|
290
|
+
@exception = params[:ex]=="" ? nil : params[:ex]
|
291
|
+
end
|
292
|
+
|
293
|
+
def filter_block
|
294
|
+
block = lambda { |j|
|
295
|
+
(!@from || j.after?(hours_ago(@from))) &&
|
296
|
+
(!@to || j.before?(hours_ago(@to))) &&
|
297
|
+
(!@klass || j.klass?(@klass)) &&
|
298
|
+
(!@exception || j.exception?(@exception)) &&
|
299
|
+
(!@sha1 || @sha1[Digest::SHA1.hexdigest(j.to_json)])
|
300
|
+
}
|
301
|
+
end
|
302
|
+
|
303
|
+
def hours_ago(h)
|
304
|
+
Time.now - h.to_i*60*60
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
# Paginate class used by resque-cleaner
|
310
|
+
|
311
|
+
#Pagination helper for list page.
|
312
|
+
class Paginate
|
313
|
+
attr_accessor :page_size, :page, :jobs, :url
|
314
|
+
|
315
|
+
def initialize(jobs, url, page=1, page_size=20)
|
316
|
+
@jobs = jobs
|
317
|
+
@url = url
|
318
|
+
@page = (!page || page < 1) ? 1 : page
|
319
|
+
@page_size = 20
|
320
|
+
end
|
321
|
+
|
322
|
+
def first_index
|
323
|
+
@page_size * (@page-1)
|
324
|
+
end
|
325
|
+
|
326
|
+
def last_index
|
327
|
+
last = first_index + @page_size - 1
|
328
|
+
last > @jobs.size-1 ? @jobs.size-1 : last
|
329
|
+
end
|
330
|
+
|
331
|
+
def paginated_jobs
|
332
|
+
@jobs[first_index, @page_size]
|
333
|
+
end
|
334
|
+
|
335
|
+
def first_page?
|
336
|
+
@page <= 1
|
337
|
+
end
|
338
|
+
|
339
|
+
def last_page?
|
340
|
+
@page >= max_page
|
341
|
+
end
|
342
|
+
|
343
|
+
def page_url(page)
|
344
|
+
u = @url
|
345
|
+
u += @url.include?("?") ? "&" : "?"
|
346
|
+
if page.is_a?(Symbol)
|
347
|
+
page = @page - 1 if page==:prev
|
348
|
+
page = @page + 1 if page==:next
|
349
|
+
end
|
350
|
+
u += "p=#{page}"
|
351
|
+
end
|
352
|
+
|
353
|
+
def total_size
|
354
|
+
@jobs.size
|
355
|
+
end
|
356
|
+
|
357
|
+
def max_page
|
358
|
+
((total_size-1) / @page_size) + 1
|
359
|
+
end
|
236
360
|
end
|
@@ -1,11 +1,4 @@
|
|
1
1
|
module ResqueHelper
|
2
|
-
#include Rack::Utils
|
3
|
-
#alias_method :h, :escape_html
|
4
|
-
|
5
|
-
|
6
|
-
def classes_in_failure
|
7
|
-
Resque.list_range(:failed,0,1000).collect{|job| job['payload']['class']}.uniq
|
8
|
-
end
|
9
2
|
|
10
3
|
def flash_helper
|
11
4
|
[:notice, :warning, :message, :error].collect do |key|
|
@@ -18,16 +11,17 @@ module ResqueHelper
|
|
18
11
|
end
|
19
12
|
|
20
13
|
def current_section
|
21
|
-
request.path_info.sub('/','').split('/')[1].downcase
|
14
|
+
request.path_info.sub('/', '').split('/')[1].downcase
|
22
15
|
end
|
23
16
|
|
24
17
|
def current_page
|
25
|
-
url request.path_info.sub('/','').downcase
|
18
|
+
url request.path_info.sub('/', '').downcase
|
26
19
|
end
|
27
20
|
|
28
21
|
def url(*path_parts)
|
29
|
-
[
|
22
|
+
[path_prefix, path_parts].join("/").squeeze('/')
|
30
23
|
end
|
24
|
+
|
31
25
|
alias_method :u, :url
|
32
26
|
|
33
27
|
def path_prefix
|
@@ -45,33 +39,33 @@ module ResqueHelper
|
|
45
39
|
|
46
40
|
def find_worker(worker)
|
47
41
|
first_part, *rest = worker.split(':')
|
48
|
-
first_part.gsub!(/_/,'.')
|
42
|
+
first_part.gsub!(/_/, '.')
|
49
43
|
Resque::Worker.find("#{first_part}:#{rest.join(':')}")
|
50
44
|
end
|
51
45
|
|
52
46
|
def redis_get_size(key)
|
53
47
|
case Resque.redis.type(key)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
48
|
+
when 'none'
|
49
|
+
[]
|
50
|
+
when 'list'
|
51
|
+
Resque.redis.llen(key)
|
52
|
+
when 'set'
|
53
|
+
Resque.redis.scard(key)
|
54
|
+
when 'string'
|
55
|
+
Resque.redis.get(key).length
|
62
56
|
end
|
63
57
|
end
|
64
58
|
|
65
59
|
def redis_get_value_as_array(key)
|
66
60
|
case Resque.redis.type(key)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
61
|
+
when 'none'
|
62
|
+
[]
|
63
|
+
when 'list'
|
64
|
+
Resque.list_range(key, 0, 20)
|
65
|
+
when 'set'
|
66
|
+
Resque.redis.smembers(key)
|
67
|
+
when 'string'
|
68
|
+
[Resque.redis.get(key)]
|
75
69
|
end
|
76
70
|
end
|
77
71
|
|
@@ -104,4 +98,43 @@ module ResqueHelper
|
|
104
98
|
def resque
|
105
99
|
Resque
|
106
100
|
end
|
101
|
+
|
102
|
+
# resque-cleaner helpers
|
103
|
+
|
104
|
+
def time_filter(id, name, value)
|
105
|
+
html = "<select id=\"#{id}\" name=\"#{name}\">"
|
106
|
+
html += "<option value=\"\">-</option>"
|
107
|
+
[1, 3, 6, 12, 24].each do |h|
|
108
|
+
selected = h.to_s == value ? 'selected="selected"' : ''
|
109
|
+
html += "<option #{selected} value=\"#{h}\">#{h} #{h==1 ? "hour" : "hours"} ago</option>"
|
110
|
+
end
|
111
|
+
[3, 7, 14, 28].each do |d|
|
112
|
+
selected = (d*24).to_s == value ? 'selected="selected"' : ''
|
113
|
+
html += "<option #{selected} value=\"#{d*24}\">#{d} days ago</option>"
|
114
|
+
end
|
115
|
+
html += "</select>"
|
116
|
+
html.html_safe
|
117
|
+
end
|
118
|
+
|
119
|
+
def class_filter(id, name, klasses, value)
|
120
|
+
html = "<select id=\"#{id}\" name=\"#{name}\">"
|
121
|
+
html += "<option value=\"\">-</option>"
|
122
|
+
klasses.each do |k|
|
123
|
+
selected = k == value ? 'selected="selected"' : ''
|
124
|
+
html += "<option #{selected} value=\"#{k}\">#{k}</option>"
|
125
|
+
end
|
126
|
+
html += "</select>"
|
127
|
+
html.html_safe
|
128
|
+
end
|
129
|
+
|
130
|
+
def exception_filter(id, name, exceptions, value)
|
131
|
+
html = "<select id=\"#{id}\" name=\"#{name}\">"
|
132
|
+
html += "<option value=\"\">-</option>"
|
133
|
+
exceptions.each do |ex|
|
134
|
+
selected = ex == value ? 'selected="selected"' : ''
|
135
|
+
html += "<option #{selected} value=\"#{ex}\">#{ex}</option>"
|
136
|
+
end
|
137
|
+
html += "</select>"
|
138
|
+
html.html_safe
|
139
|
+
end
|
107
140
|
end
|
@@ -6,6 +6,7 @@
|
|
6
6
|
<%= yield :javascript %>
|
7
7
|
<%= stylesheet_link_tag "resque/resque_reset", :media=>"screen" %>
|
8
8
|
<%= stylesheet_link_tag "resque/resque", :media=>"screen" %>
|
9
|
+
<%= stylesheet_link_tag "resque_cleaner/cleaner", :media=>"screen" %>
|
9
10
|
<%= yield :stylesheets %>
|
10
11
|
</head>
|
11
12
|
<body>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="warning">
|
2
|
+
<p>
|
3
|
+
There are more than <%= @cleaner.limiter.maximum%> jobs. ResqueCleaner handles only recent <%= @cleaner.limiter.maximum %> jobs. See the Limiter section on <a href="https://github.com/ono/resque-cleaner" target="_blank">README</a> for more detail.
|
4
|
+
</p>
|
5
|
+
<p>
|
6
|
+
<form method="post" action="cleaner_stale">
|
7
|
+
<input type="hidden" name="action" value="clear_stale" />
|
8
|
+
<input type="submit" onclick="return confirm('Are you sure?')" value="Clear all jobs older than <%= @cleaner.limiter.count %>th job."/>
|
9
|
+
(<%= @cleaner.failure.count - @cleaner.limiter.maximum %> jobs will be cleared)
|
10
|
+
</form>
|
11
|
+
</p>
|
12
|
+
</div>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<div class="list_info clearfix">
|
2
|
+
|
3
|
+
<ul class="pagination">
|
4
|
+
<li class="summary">
|
5
|
+
<%= @paginate.first_index + 1%> - <%= @paginate.last_index + 1%> / <%= @paginate.total_size%>
|
6
|
+
</li>
|
7
|
+
<% if @paginate.max_page>1 %>
|
8
|
+
<% if @paginate.first_page? %>
|
9
|
+
<li class="prev off"><<newer</li>
|
10
|
+
<% else %>
|
11
|
+
<li class="prev"><a href="<%= @paginate.page_url(:prev)%>"><<newer</a></li>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% 1.upto(6<@paginate.max_page ? 6 : @paginate.max_page) do |pg| %>
|
15
|
+
<% if @paginate.page==pg %>
|
16
|
+
<li class="current"><%=pg%></li>
|
17
|
+
<% else %>
|
18
|
+
<li><a href="<%= @paginate.page_url(pg)%>"><%=pg%></a></li>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<% if @paginate.max_page > 6 %>
|
23
|
+
<% if @paginate.max_page!=@paginate.page %>
|
24
|
+
<% if @paginate.page>7 %>
|
25
|
+
<li class="off">...</li>
|
26
|
+
<% end %>
|
27
|
+
<% if @paginate.page>6 %>
|
28
|
+
<li class="current"><%=@paginate.page%></li>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
<% if @paginate.max_page>7 && @paginate.page+1!=@paginate.max_page %>
|
32
|
+
<li class="off">...</li>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% if @paginate.max_page==@paginate.page %>
|
36
|
+
<li class="current"><%=@paginate.max_page%></li>
|
37
|
+
<% else %>
|
38
|
+
<li><a href="<%= @paginate.page_url(@paginate.max_page)%>"><%=@paginate.max_page%></a></li>
|
39
|
+
<% end %>
|
40
|
+
<% end %>
|
41
|
+
|
42
|
+
<% if @paginate.last_page? %>
|
43
|
+
<li class="next off">older>></li>
|
44
|
+
<% else %>
|
45
|
+
<li class="next"><a href="<%= @paginate.page_url(:next)%>">older>></a></li>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
</ul>
|
50
|
+
<div class="dump">
|
51
|
+
<a href="<%= @dump_url%>" target="_blank">Dump</a>
|
52
|
+
</div>
|
53
|
+
</div>
|
@@ -15,7 +15,7 @@
|
|
15
15
|
<% for job in (jobs = resque.peek(queue, start, 20)) %>
|
16
16
|
<tr>
|
17
17
|
<td class='class'><%= job['class'] %></td>
|
18
|
-
<td class='args'><%=
|
18
|
+
<td class='args'><%= job['args'].inspect.html_safe %></td>
|
19
19
|
<td>
|
20
20
|
<%= button_to "Remove", {:controller=>'resque', :action=> 'remove_job',:class => job['class'], :args => Resque.encode(job['args'])}, :class => 'clear-failed', :method => :post %>
|
21
21
|
</td>
|
@@ -44,7 +44,7 @@
|
|
44
44
|
</tr>
|
45
45
|
<% end %>
|
46
46
|
<tr class='failed'>
|
47
|
-
<td class='queue failed'><%= link_to('failed', {:action => "
|
47
|
+
<td class='queue failed'><%= link_to('failed', {:action => "cleaner"}, :class => 'queue') %></td>
|
48
48
|
<td class='size'><%= Resque::Failure.count %></td>
|
49
49
|
</tr>
|
50
50
|
</table>
|