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.
Files changed (45) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +3 -0
  3. data/History.txt +4 -0
  4. data/README.markdown +9 -5
  5. data/Rakefile +1 -1
  6. data/VERSION.yml +1 -1
  7. data/app/assets/stylesheets/resque_cleaner/cleaner.css +62 -0
  8. data/app/controllers/resque_controller.rb +167 -43
  9. data/app/helpers/resque_helper.rb +60 -27
  10. data/app/views/layouts/resque.html.erb +1 -0
  11. data/app/views/resque/_limiter.html.erb +12 -0
  12. data/app/views/resque/_paginate.html.erb +53 -0
  13. data/app/views/resque/_queues.html.erb +2 -2
  14. data/app/views/resque/_working.html.erb +1 -1
  15. data/app/views/resque/cleaner.html.erb +41 -0
  16. data/app/views/resque/cleaner_exec.html.erb +6 -0
  17. data/app/views/resque/cleaner_list.html.erb +172 -0
  18. data/app/views/resque/delayed_timestamp.html.erb +1 -1
  19. data/lib/resque_ui.rb +2 -1
  20. data/rdoc/Resque/ChainedJobWithStatus.html +0 -2
  21. data/rdoc/Resque/Job.html +0 -2
  22. data/rdoc/Resque/JobWithStatus.html +0 -2
  23. data/rdoc/Resque/Status.html +0 -2
  24. data/rdoc/Resque/Worker.html +0 -2
  25. data/rdoc/Resque.html +0 -7
  26. data/rdoc/ResqueScheduler.html +0 -2
  27. data/rdoc/ResqueUi/Cap.html +0 -2
  28. data/rdoc/ResqueUi/Engine.html +0 -2
  29. data/rdoc/ResqueUi.html +0 -2
  30. data/rdoc/created.rid +3 -4
  31. data/rdoc/index.html +3 -7
  32. data/rdoc/lib/resque_ui/cap_rb.html +1 -1
  33. data/rdoc/lib/resque_ui/cap_recipes_rb.html +1 -1
  34. data/rdoc/lib/resque_ui/overrides/resque/job_rb.html +1 -1
  35. data/rdoc/lib/resque_ui/overrides/resque/resque_rb.html +1 -1
  36. data/rdoc/lib/resque_ui/overrides/resque/worker_rb.html +1 -1
  37. data/rdoc/lib/resque_ui/overrides/resque_scheduler/resque_scheduler_rb.html +1 -1
  38. data/rdoc/lib/resque_ui/overrides/resque_status/chained_job_with_status_rb.html +1 -1
  39. data/rdoc/lib/resque_ui/overrides/resque_status/job_with_status_rb.html +1 -1
  40. data/rdoc/lib/resque_ui/overrides/resque_status/status_rb.html +1 -1
  41. data/rdoc/lib/resque_ui_rb.html +4 -4
  42. data/resque_ui.gemspec +12 -5
  43. metadata +20 -5
  44. data/app/views/resque/failed.html.erb +0 -54
  45. data/lib/resque_ui/overrides/resque/failure/failure.rb +0 -22
data/Gemfile CHANGED
@@ -4,3 +4,4 @@ gem 'rails', '>= 3.0.0'
4
4
  gem 'redis', '>= 2.1.3'
5
5
  gem 'resque', '>= 1.5'
6
6
  gem 'resque-status', '>= 0.2.2'
7
+ gem 'resque-cleaner', '>= 0.2.6'
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
@@ -1,3 +1,7 @@
1
+ == 3.1.0 2011-09-22
2
+
3
+ * Added Resque Cleaner to manage the failed queue. Removed the Failed tab.
4
+
1
5
  == 3.0.0 2011-09-16
2
6
 
3
7
  * converted plugging to a gem/engine for Rails 3
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 as well.
35
+ This engine now requires the resque-status 0.2.2 or higher gem.
36
36
 
37
- These gems will all be installed for automatically when you install resque_ui.
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 ability to restart failed jobs, and clear individual failed jobs from the list
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
- ![Restart Failed Jobs](http://img.skitch.com/20100308-mbh5s8pcw5n4ei2hrseiqtshys.png)
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 File.dirname(__FILE__) + '/../vendor/engines/resque_ui/lib/resque_ui/cap_recipes'
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{http://kevintyll.git.com/resque_ui}
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
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 3
3
- :minor: 0
3
+ :minor: 1
4
4
  :patch: 0
5
5
  :build:
@@ -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
- [ path_prefix, path_parts ].join("/").squeeze('/')
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
- when 'none'
55
- []
56
- when 'list'
57
- Resque.redis.llen(key)
58
- when 'set'
59
- Resque.redis.scard(key)
60
- when 'string'
61
- Resque.redis.get(key).length
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
- when 'none'
68
- []
69
- when 'list'
70
- Resque.list_range(key, 0, 20)
71
- when 'set'
72
- Resque.redis.smembers(key)
73
- when 'string'
74
- [Resque.redis.get(key)]
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">&lt;&lt;newer</li>
10
+ <% else %>
11
+ <li class="prev"><a href="<%= @paginate.page_url(:prev)%>">&lt;&lt;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&gt;&gt;</li>
44
+ <% else %>
45
+ <li class="next"><a href="<%= @paginate.page_url(:next)%>">older&gt;&gt;</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'><%=h job['args'].inspect %></td>
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 => "failed"}, :class => 'queue') %></td>
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>
@@ -21,7 +21,7 @@
21
21
  <td>
22
22
  <code><%= data['payload']['class'] %></code>
23
23
  </td>
24
- <td><%=h data['payload']['args'].inspect %></td>
24
+ <td><%= data['payload']['args'].inspect.html_safe %></td>
25
25
  </tr>
26
26
  </table>
27
27