resque_ui 3.0.0 → 3.1.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.
- 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>
|