resque-web-clone 0.0.6
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.
- checksums.yaml +7 -0
- data/README.md +89 -0
- data/Rakefile +34 -0
- data/app/assets/images/resque_web/idle.png +0 -0
- data/app/assets/images/resque_web/lifebuoy.png +0 -0
- data/app/assets/images/resque_web/poll.png +0 -0
- data/app/assets/images/resque_web/rails.png +0 -0
- data/app/assets/images/resque_web/working.png +0 -0
- data/app/assets/javascripts/resque_web/application.js +16 -0
- data/app/assets/javascripts/resque_web/bootstrap.js.coffee +4 -0
- data/app/assets/javascripts/resque_web/failure.js.coffee +7 -0
- data/app/assets/javascripts/resque_web/jquery.relative-date.js +47 -0
- data/app/assets/javascripts/resque_web/polling.js.coffee +25 -0
- data/app/assets/javascripts/resque_web/relative_date.js.coffee +27 -0
- data/app/assets/stylesheets/resque_web/application.css +13 -0
- data/app/assets/stylesheets/resque_web/bootstrap_and_overrides.css.scss.erb +146 -0
- data/app/controllers/resque_web/application_controller.rb +25 -0
- data/app/controllers/resque_web/failures_controller.rb +62 -0
- data/app/controllers/resque_web/overview_controller.rb +7 -0
- data/app/controllers/resque_web/queues_controller.rb +22 -0
- data/app/controllers/resque_web/stats_controller.rb +36 -0
- data/app/controllers/resque_web/workers_controller.rb +34 -0
- data/app/controllers/resque_web/working_controller.rb +8 -0
- data/app/helpers/resque_web/application_helper.rb +69 -0
- data/app/helpers/resque_web/failures_helper.rb +58 -0
- data/app/helpers/resque_web/overview_helper.rb +6 -0
- data/app/helpers/resque_web/queues_helper.rb +72 -0
- data/app/helpers/resque_web/stats_helper.rb +54 -0
- data/app/helpers/resque_web/workers_helper.rb +16 -0
- data/app/helpers/resque_web/working_helper.rb +19 -0
- data/app/views/layouts/resque_web/application.html.erb +58 -0
- data/app/views/resque_web/failures/_failed_job.html.erb +53 -0
- data/app/views/resque_web/failures/_overview.html.erb +24 -0
- data/app/views/resque_web/failures/index.html.erb +32 -0
- data/app/views/resque_web/failures/show.html.erb +20 -0
- data/app/views/resque_web/overview/show.html.erb +4 -0
- data/app/views/resque_web/queues/_queues.html.erb +4 -0
- data/app/views/resque_web/queues/_queues_advanced.html.erb +14 -0
- data/app/views/resque_web/queues/_queues_basic.html.erb +17 -0
- data/app/views/resque_web/queues/index.html.erb +1 -0
- data/app/views/resque_web/queues/show.html.erb +30 -0
- data/app/views/resque_web/stats/key.html.erb +26 -0
- data/app/views/resque_web/stats/keys.html.erb +17 -0
- data/app/views/resque_web/stats/redis.html.erb +14 -0
- data/app/views/resque_web/stats/resque.html.erb +14 -0
- data/app/views/resque_web/workers/index.html.erb +19 -0
- data/app/views/resque_web/workers/show.html.erb +38 -0
- data/app/views/resque_web/working/_working.html.erb +34 -0
- data/app/views/resque_web/working/index.html.erb +1 -0
- data/config/initializers/resque_config.rb +2 -0
- data/config/routes.rb +34 -0
- data/lib/resque_web/engine.rb +13 -0
- data/lib/resque_web/version.rb +3 -0
- data/lib/resque_web.rb +4 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/functional/failures_controller_test.rb +74 -0
- data/test/functional/overview_controller_test.rb +37 -0
- data/test/functional/queues_controller_test.rb +58 -0
- data/test/functional/stats_controller_test.rb +70 -0
- data/test/functional/workers_controller_test.rb +26 -0
- data/test/functional/working_controller_test.rb +19 -0
- data/test/integration/plugin_integration_test.rb +72 -0
- data/test/support/controller_test_helpers.rb +22 -0
- data/test/test_helper.rb +23 -0
- data/test/unit/helpers/failures_helper_test.rb +15 -0
- data/test/unit/helpers/jobs_helper_test.rb +4 -0
- data/test/unit/helpers/overview_helper_test.rb +4 -0
- data/test/unit/helpers/queues_helper_test.rb +4 -0
- data/test/unit/helpers/retry_controller_helper_test.rb +4 -0
- data/test/unit/helpers/stats_helper_test.rb +4 -0
- data/test/unit/helpers/workers_helper_test.rb +4 -0
- data/test/unit/helpers/working_helper_test.rb +4 -0
- metadata +263 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
|
|
4
|
+
PER_PAGE = 20
|
|
5
|
+
|
|
6
|
+
def tabs
|
|
7
|
+
t = {'overview' => ResqueWeb::Engine.app.url_helpers.overview_path,
|
|
8
|
+
'working' => ResqueWeb::Engine.app.url_helpers.working_index_path,
|
|
9
|
+
'failures' => ResqueWeb::Engine.app.url_helpers.failures_path,
|
|
10
|
+
'queues' => ResqueWeb::Engine.app.url_helpers.queues_path,
|
|
11
|
+
'workers' => ResqueWeb::Engine.app.url_helpers.workers_path,
|
|
12
|
+
'stats' => ResqueWeb::Engine.app.url_helpers.stats_path
|
|
13
|
+
}
|
|
14
|
+
ResqueWeb::Plugins.plugins.each do |p|
|
|
15
|
+
p.tabs.each { |tab| t.merge!(tab) }
|
|
16
|
+
end
|
|
17
|
+
t
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def tab(name,path)
|
|
21
|
+
content_tag :li, link_to(name.capitalize, path), :class => current_tab?(name) ? "active" : nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def current_tab
|
|
25
|
+
params[:controller].gsub(/resque_web\//, "#{root_path}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def current_tab?(name)
|
|
29
|
+
params[:controller] == name.to_s
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_reader :subtabs
|
|
33
|
+
|
|
34
|
+
def subtab(name)
|
|
35
|
+
content_tag :li, link_to(name, "#{current_tab}/#{name}"), :class => current_subtab?(name) ? "current" : nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def current_subtab?(name)
|
|
39
|
+
params[:id] == name.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def pagination(options = {})
|
|
43
|
+
start = options[:start] || 1
|
|
44
|
+
per_page = options[:per_page] || PER_PAGE
|
|
45
|
+
total = options[:total] || 0
|
|
46
|
+
return if total < per_page
|
|
47
|
+
|
|
48
|
+
markup = ""
|
|
49
|
+
if start - per_page >= 0
|
|
50
|
+
markup << link_to(raw("« less"), params.merge(:start => start - per_page), :class => 'btn less')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if start + per_page <= total
|
|
54
|
+
markup << link_to(raw("more »"), params.merge(:start => start + per_page), :class => 'btn more')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
content_tag :p, raw(markup), :class => 'pagination'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def poll(polling=false)
|
|
61
|
+
if polling
|
|
62
|
+
text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}".html_safe
|
|
63
|
+
else
|
|
64
|
+
text = "<a href='#{h(request.path)}' rel='poll'>Live Poll</a>".html_safe
|
|
65
|
+
end
|
|
66
|
+
content_tag :p, text, :class => 'poll'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
module FailuresHelper
|
|
3
|
+
def each_failure(&block)
|
|
4
|
+
Resque::Failure.each(failure_start_at, failure_per_page, params[:queue], params[:class], &block)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def failure_date_format
|
|
8
|
+
"%Y/%m/%d %T %z"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def multiple_failure_queues?
|
|
12
|
+
@multiple_failure_queues ||= Resque::Failure.queues.size > 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def failure_queue
|
|
16
|
+
multiple_failure_queues? ? params[:id] : 'failed'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def failure_queue_name
|
|
20
|
+
@failure_queue_name ||= params[:queue] ? params[:queue] : 'Failed'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def failure_size
|
|
24
|
+
@failure_size ||= Resque::Failure.count(params[:id], params[:class])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def failure_per_page
|
|
28
|
+
@failures_per_page ||= params[:class] ? failure_size : 20
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def failure_start_at
|
|
32
|
+
params[:start].to_i
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def failure_end_at
|
|
36
|
+
if failure_start_at + failure_per_page > failure_size
|
|
37
|
+
failure_size
|
|
38
|
+
else
|
|
39
|
+
failure_start_at + failure_per_page
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def failure_class_counts(queue = params[:id])
|
|
44
|
+
classes = Hash.new(0)
|
|
45
|
+
Resque::Failure.each(0, Resque::Failure.count(queue), queue) do |_, item|
|
|
46
|
+
class_name = item['payload']['class'] if item['payload']
|
|
47
|
+
class_name ||= "nil"
|
|
48
|
+
classes[class_name] += 1
|
|
49
|
+
end
|
|
50
|
+
classes.sort_by { |name,_| name }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def job_arguments(job)
|
|
54
|
+
return 'nil' unless job['payload']
|
|
55
|
+
Array(job['payload']['args']).map { |arg| arg.inspect }.join("\n")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'resque/failure/redis_multi_queue'
|
|
2
|
+
|
|
3
|
+
module ResqueWeb
|
|
4
|
+
module QueuesHelper
|
|
5
|
+
def queues_partial_name
|
|
6
|
+
if Resque::Failure.backend == Resque::Failure::RedisMultiQueue
|
|
7
|
+
'resque_web/queues/queues_advanced'
|
|
8
|
+
else
|
|
9
|
+
'resque_web/queues/queues_basic'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def queue_names
|
|
14
|
+
Resque.queues.sort_by(&:to_s)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def queue_start_at
|
|
18
|
+
params[:start].to_i
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def queue_end_at
|
|
22
|
+
if queue_start_at + queue_per_page > queue_size
|
|
23
|
+
queue_size
|
|
24
|
+
else
|
|
25
|
+
queue_start_at + queue_per_page
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def queue_per_page
|
|
30
|
+
20
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def queue_size(queue_name = params[:id])
|
|
34
|
+
Resque.size queue_name
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def queue_jobs
|
|
38
|
+
@queue_jobs ||= Resque.peek(params[:id], queue_start_at, queue_per_page)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def failed_queue_names
|
|
42
|
+
Resque::Failure.queues.sort_by(&:to_s)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def failed_queue_name(original_queue_name)
|
|
46
|
+
"#{original_queue_name}_failed"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def failed_queue_class(queue_name)
|
|
50
|
+
Resque::Failure.count(queue_name).zero? ? "failed" : "failure"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def failed_queue_size(queue_name)
|
|
54
|
+
Resque::Failure.count(queue_name)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def failed_queue_info(queue_name)
|
|
58
|
+
failed_queue = failed_queue_name(queue_name)
|
|
59
|
+
size = failed_queue_size(failed_queue)
|
|
60
|
+
|
|
61
|
+
if size > 0
|
|
62
|
+
css_class = "badge badge-important"
|
|
63
|
+
badge = link_to(size, failure_path(failed_queue))
|
|
64
|
+
else
|
|
65
|
+
css_class = "badge"
|
|
66
|
+
badge = size.to_s
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
raw "<span class=\"#{css_class}\">#{badge}</span>"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
module StatsHelper
|
|
3
|
+
def resque_info
|
|
4
|
+
Resque.info.sort_by { |i| i[0].to_s }
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def redis_info
|
|
8
|
+
Resque.redis.info.to_a.sort_by { |i| i[0].to_s }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def redis_key_type(key)
|
|
12
|
+
Resque.redis.type(key)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def redis_key_size(key)
|
|
16
|
+
# FIXME: there's a potential race in this method if a key is modified
|
|
17
|
+
# "in flight". Not sure how to fix it, unfortunately :(
|
|
18
|
+
case redis_key_type(key)
|
|
19
|
+
when 'none'
|
|
20
|
+
0
|
|
21
|
+
when 'list'
|
|
22
|
+
Resque.redis.llen(key)
|
|
23
|
+
when 'set'
|
|
24
|
+
Resque.redis.scard(key)
|
|
25
|
+
when 'string'
|
|
26
|
+
string = Resque.redis.get(key)
|
|
27
|
+
string ? string.length : 0
|
|
28
|
+
when 'zset'
|
|
29
|
+
Resque.redis.zcard(key)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def redis_get_array(key, start=0)
|
|
34
|
+
case redis_key_type(key)
|
|
35
|
+
when 'none'
|
|
36
|
+
[]
|
|
37
|
+
when 'list'
|
|
38
|
+
Resque.redis.lrange(key, start, start + 20)
|
|
39
|
+
when 'set'
|
|
40
|
+
Resque.redis.smembers(key)[start..(start + 20)]
|
|
41
|
+
when 'string'
|
|
42
|
+
[Resque.redis.get(key)]
|
|
43
|
+
when 'zset'
|
|
44
|
+
Resque.redis.zrange(key, start, start + 20)
|
|
45
|
+
when 'hash'
|
|
46
|
+
Resque.redis.hgetall(key)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def current_subtab?(name)
|
|
51
|
+
params[:action] == name.to_s
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
module WorkersHelper
|
|
3
|
+
def worker_hosts
|
|
4
|
+
@worker_hosts ||= begin
|
|
5
|
+
hosts = Hash.new { [] }
|
|
6
|
+
|
|
7
|
+
Resque.workers.each do |worker|
|
|
8
|
+
host, _ = worker.to_s.split(':')
|
|
9
|
+
hosts[host] += [worker.to_s]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
hosts
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
module WorkingHelper
|
|
3
|
+
def workers
|
|
4
|
+
@workers ||= Resque.workers
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def jobs
|
|
8
|
+
@jobs ||= workers.map(&:job)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def worker_jobs
|
|
12
|
+
@worker_jobs ||= workers.zip(jobs).reject { |w, j| w.idle? || j['queue'].nil? }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def sorted_worker_jobs
|
|
16
|
+
@sorted_worker_jobs ||= worker_jobs.sort_by { |w, j| j['run_at'] || '' }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
6
|
+
<meta name="description" content="">
|
|
7
|
+
<meta name="viewport" content="width=device-width">
|
|
8
|
+
<title>Resque.</title>
|
|
9
|
+
<%= stylesheet_link_tag "resque_web/application", :media => "all" %>
|
|
10
|
+
<%= javascript_include_tag "resque_web/application" %>
|
|
11
|
+
<%= csrf_meta_tags %>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
|
|
15
|
+
<div class="navbar navbar-inverse navbar-fixed-top">
|
|
16
|
+
<div class="navbar-inner">
|
|
17
|
+
<div class="container">
|
|
18
|
+
<a class="btn btn-navbar navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
|
|
19
|
+
<span class="icon-bar"></span>
|
|
20
|
+
<span class="icon-bar"></span>
|
|
21
|
+
<span class="icon-bar"></span>
|
|
22
|
+
</a>
|
|
23
|
+
<%= image_tag "resque_web/lifebuoy.png", class: 'logo' %>
|
|
24
|
+
<%= link_to "Resque", ResqueWeb::Engine.app.url_helpers.root_path, :class => "brand navbar-brand" %>
|
|
25
|
+
<div class="nav-collapse navbar-collapse collapse">
|
|
26
|
+
<ul class="nav navbar-nav">
|
|
27
|
+
<% tabs.each do |tab_name,path| %>
|
|
28
|
+
<%= tab tab_name,path %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</ul>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<% unless subtabs.empty? %>
|
|
37
|
+
<ul class="nav subnav">
|
|
38
|
+
<div class="container">
|
|
39
|
+
<% subtabs.each do |tab_name| %>
|
|
40
|
+
<%= subtab tab_name %>
|
|
41
|
+
<% end %>
|
|
42
|
+
</div>
|
|
43
|
+
</ul>
|
|
44
|
+
<% end %>
|
|
45
|
+
|
|
46
|
+
<div class="container" id="main">
|
|
47
|
+
<%= yield %>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<footer id="footer">
|
|
51
|
+
<div class="container">
|
|
52
|
+
<p>Powered by <a href="http://github.com/resque/resque">Resque</a> v<%=Resque::Version%></p>
|
|
53
|
+
<p>Connected to Redis namespace <%= Resque.redis.namespace %> on <%=Resque.redis_id%></p>
|
|
54
|
+
</div>
|
|
55
|
+
</footer>
|
|
56
|
+
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<li>
|
|
2
|
+
<dl>
|
|
3
|
+
<% if job.nil? %>
|
|
4
|
+
<dt>Error</dt>
|
|
5
|
+
<dd>Job <%= id %> could not be parsed; perhaps it contains invalid JSON?</dd>
|
|
6
|
+
<% else %>
|
|
7
|
+
<dt>Worker</dt>
|
|
8
|
+
<dd>
|
|
9
|
+
<%= job['worker'].split(':')[0...2].join(':') %>
|
|
10
|
+
on <b class="label label-info"><%= job['queue'] %></b >
|
|
11
|
+
at <b><span class="time"><%= Time.parse(job['failed_at']).strftime(failure_date_format) %></span></b>
|
|
12
|
+
|
|
13
|
+
<% if job['retried_at'] %>
|
|
14
|
+
<div class="retried">
|
|
15
|
+
Retried <b><span class="time"><%= Time.parse(job['retried_at']).strftime(failure_date_format) %></span></b>
|
|
16
|
+
<%= link_to "Remove", failure_path(:queue=>failure_queue,:id=>id), :method => :delete, :class => 'remove', :rel => 'remove' %>
|
|
17
|
+
</div>
|
|
18
|
+
<% else %>
|
|
19
|
+
<div class="controls">
|
|
20
|
+
<%= link_to "Retry", retry_failure_path(:queue=>failure_queue,:id=>id), :method => :put %>
|
|
21
|
+
or
|
|
22
|
+
<%= link_to "Remove", failure_path(:queue=>failure_queue,:id=>id), :method => :delete %>
|
|
23
|
+
</div>
|
|
24
|
+
<% end %>
|
|
25
|
+
</dd>
|
|
26
|
+
<dt>Class</dt>
|
|
27
|
+
<dd>
|
|
28
|
+
<% if job['payload'] && job['payload']['class'] %>
|
|
29
|
+
<%= link_to failures_path(:class=>job['payload']['class'],:queue=>params[:queue]) do %>
|
|
30
|
+
<code><%= job['payload']['class'] %></code>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% else %>
|
|
33
|
+
<code>nil</code>
|
|
34
|
+
<% end %>
|
|
35
|
+
</dd>
|
|
36
|
+
<dt>Arguments</dt>
|
|
37
|
+
<dd><pre><%= job_arguments(job) %></pre></dd>
|
|
38
|
+
<dt>Exception</dt>
|
|
39
|
+
<dd><code><%= job['exception'] %></code></dd>
|
|
40
|
+
<dt>Error</dt>
|
|
41
|
+
<dd class="error">
|
|
42
|
+
<% if job['backtrace'] %>
|
|
43
|
+
<a href="#" class="backtrace"><%= job['error'] %></a>
|
|
44
|
+
<pre style='display:none'><%=h job['backtrace'].join("\n") %></pre>
|
|
45
|
+
<% else %>
|
|
46
|
+
<%=h job['error'] %>
|
|
47
|
+
<% end %>
|
|
48
|
+
</dd>
|
|
49
|
+
<% end %>
|
|
50
|
+
</dl>
|
|
51
|
+
<div class="r">
|
|
52
|
+
</div>
|
|
53
|
+
</li>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<table class="table table-bordered" id="failed">
|
|
2
|
+
<tbody>
|
|
3
|
+
<tr class="total">
|
|
4
|
+
<td class="queue">Total Failed</td>
|
|
5
|
+
<td class="center"><%= Resque::Failure.count %></td>
|
|
6
|
+
</tr>
|
|
7
|
+
|
|
8
|
+
<% Resque::Failure.queues.sort.each do |queue| %>
|
|
9
|
+
<tr>
|
|
10
|
+
<th><%= link_to queue, failure_path(queue), :class => 'label label-info' %></th>
|
|
11
|
+
<th style="width:75px;" class="center"><%= Resque::Failure.count(queue) %></th>
|
|
12
|
+
</tr>
|
|
13
|
+
|
|
14
|
+
<% failure_class_counts(queue).each do |klass, count| %>
|
|
15
|
+
<tr id="<%= klass %>">
|
|
16
|
+
<td>
|
|
17
|
+
<%= link_to klass, failure_path(queue, :class => klass), :class => "failed failed_class" %>
|
|
18
|
+
</td>
|
|
19
|
+
<td style="text-align: center;" class="failed<%= (count.to_i > 1000) ? '_many' : '' %>"><%= count %></td>
|
|
20
|
+
</tr>
|
|
21
|
+
<% end %>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tbody>
|
|
24
|
+
</table>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<% if multiple_failure_queues? && !params[:queue] %>
|
|
2
|
+
<h1>All Failure Queues</h1>
|
|
3
|
+
<% else %>
|
|
4
|
+
<h1>Failed Jobs <%= "on '#{params[:queue]}'" if params[:queue] %> <%= "with class '#{params[:class]}'" if params[:class] %></h1>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<% unless failure_size.zero? %>
|
|
8
|
+
<%= form_tag(destroy_all_failures_path(queue: params[:queue]), method: :delete) do %>
|
|
9
|
+
<%= submit_tag "Clear #{failure_queue_name} Jobs", class: 'btn btn-danger', data: { confirm: "Are you sure you want to clear ALL #{failure_queue_name.downcase} jobs?" } %>
|
|
10
|
+
<% if failure_size > failure_per_page %>
|
|
11
|
+
<%= link_to "Last page »".html_safe, { start: (failure_size - failure_per_page) }, class: 'btn' %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
<%= form_tag(retry_all_failures_path(queue: params[:queue]), method: :put) do %>
|
|
15
|
+
<%= submit_tag "Retry #{failure_queue_name} Jobs", class: 'btn', data: { confirm: "Are you sure you want to retry ALL #{failure_queue_name.downcase} jobs?" } %>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<% if multiple_failure_queues? && !params[:queue] %>
|
|
20
|
+
<p class="sub"><b><%= Resque::Failure.queues.size %></b> failure queues total</sub>
|
|
21
|
+
<%= render partial: 'overview' %>
|
|
22
|
+
<% else %>
|
|
23
|
+
<p class="sub">Showing <%= failure_start_at %> to <%= failure_end_at %> of <b><%= failure_size %></b> jobs</p>
|
|
24
|
+
|
|
25
|
+
<ul class="failed">
|
|
26
|
+
<% each_failure do |id, job| %>
|
|
27
|
+
<%= render partial: 'failed_job', locals: { id: id, job: job } %>
|
|
28
|
+
<% end %>
|
|
29
|
+
</ul>
|
|
30
|
+
|
|
31
|
+
<%= pagination(start: failure_start_at, total: failure_size) unless params[:class] %>
|
|
32
|
+
<% end %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<h1>Failed Jobs <%= "on '#{params[:id]}'" if params[:id] %> <%= "with class '#{params[:class]}'" if params[:class] %></h1>
|
|
2
|
+
|
|
3
|
+
<% if @jobs.any? %>
|
|
4
|
+
<%= form_tag("/failures/#{params[:id] if params[:id]}", :method => :delete) do %>
|
|
5
|
+
<%= submit_tag "Clear #{params[:id] ? "'#{params[:id]}'" : 'Failed'} Jobs", :confirm => "Are you sure?", :class => 'btn btn-danger' %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<%= form_tag("/failures/#{params[:id] ? params[:id] : "all"}/retry") do %>
|
|
8
|
+
<%= submit_tag "Retry #{params[:id] ? "'#{params[:id]}'" : 'Failed'} Jobs", :class => 'btn' %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
|
|
12
|
+
<p class="sub">Showing <%= failure_start_at %> to <%= failure_end_at %> of <b><%= failure_size %></b> jobs</p>
|
|
13
|
+
|
|
14
|
+
<ul class="failed">
|
|
15
|
+
<% @jobs.each do |id, job| %>
|
|
16
|
+
<%= render :partial => 'failed_job', :locals => {:id => id, :job => job} %>
|
|
17
|
+
<% end %>
|
|
18
|
+
</ul>
|
|
19
|
+
|
|
20
|
+
<%= pagination :start => failure_start_at, :total => failure_size unless params[:class] %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<table class="table table-bordered queues">
|
|
2
|
+
<tr>
|
|
3
|
+
<th>Name</th>
|
|
4
|
+
<th>Jobs</th>
|
|
5
|
+
<th>Failures</th>
|
|
6
|
+
</tr>
|
|
7
|
+
<% queue_names.each do |queue_name| %>
|
|
8
|
+
<tr>
|
|
9
|
+
<td class="queue"><%= link_to queue_name, queue_path(queue_name) %></td>
|
|
10
|
+
<td class="size"><%= queue_size(queue_name) %></td>
|
|
11
|
+
<td class="failure"><%= failed_queue_info(queue_name) %></td>
|
|
12
|
+
</tr>
|
|
13
|
+
<% end %>
|
|
14
|
+
</table>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<table class="table table-bordered queues">
|
|
2
|
+
<tr>
|
|
3
|
+
<th>Name</th>
|
|
4
|
+
<th>Jobs</th>
|
|
5
|
+
</tr>
|
|
6
|
+
<% queue_names.each do |queue_name| %>
|
|
7
|
+
<tr>
|
|
8
|
+
<td class="queue"><%= link_to queue_name, queue_path(queue_name) %></td>
|
|
9
|
+
<td class="size"><%= queue_size(queue_name) %></td>
|
|
10
|
+
</tr>
|
|
11
|
+
<% end %>
|
|
12
|
+
|
|
13
|
+
<tr class="<%= failed_queue_class('failed') %> first_failure">
|
|
14
|
+
<td class="queue failed"><%= link_to 'failed', failures_path, :class => 'queue' %></td>
|
|
15
|
+
<td class="size"><%= failed_queue_size('failed') %></td>
|
|
16
|
+
</tr>
|
|
17
|
+
</table>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'queues' %>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<h1>Pending jobs on <span class='hl'><%= params[:id] %></span></h1>
|
|
2
|
+
|
|
3
|
+
<%= form_tag(clear_queue_path(params[:id]), :method => :put) do %>
|
|
4
|
+
<%= submit_tag "Clear Pending Jobs", :class => 'btn btn-danger', :data => { :confirm => "Are you absolutely sure? This cannot be undone." } %>
|
|
5
|
+
<% end % %>
|
|
6
|
+
|
|
7
|
+
<%= form_tag(queue_path(params[:id]), :method => :delete, :class => 'remove-queue') do %>
|
|
8
|
+
<%= submit_tag "Remove Queue", :class => 'btn btn-danger', :data => { :confirm => "Are you absolutely sure? This cannot be undone." } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
|
|
11
|
+
<p class="sub">Showing <%= queue_start_at %> to <%= queue_end_at %> of <b><%= queue_size %></b> jobs</p>
|
|
12
|
+
<table class="table table-bordered jobs">
|
|
13
|
+
<tr>
|
|
14
|
+
<th>Class</th>
|
|
15
|
+
<th>Args</th>
|
|
16
|
+
</tr>
|
|
17
|
+
<% queue_jobs.each do |job| %>
|
|
18
|
+
<tr>
|
|
19
|
+
<td class='class'><%= job['class'] %></td>
|
|
20
|
+
<td class='args'><%=h job['args'].inspect %></td>
|
|
21
|
+
</tr>
|
|
22
|
+
<% end %>
|
|
23
|
+
<% if queue_jobs.empty? %>
|
|
24
|
+
<tr>
|
|
25
|
+
<td class='no-data' colspan='2'>There are no pending jobs in this queue</td>
|
|
26
|
+
</tr>
|
|
27
|
+
<% end %>
|
|
28
|
+
</table>
|
|
29
|
+
|
|
30
|
+
<%= pagination :start => queue_start_at, :total => queue_size %>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<% if redis_key_type(params[:key]) == 'string' %>
|
|
2
|
+
<h1>Key "<%= params[:id] %>" is a string</h1>
|
|
3
|
+
<h2>size: <%= redis_key_size(params[:id]) %></h2>
|
|
4
|
+
<table class="table table-bordered">
|
|
5
|
+
<tr>
|
|
6
|
+
<td><%= redis_get_array(key) %></td>
|
|
7
|
+
</tr>
|
|
8
|
+
</table>
|
|
9
|
+
<% else %>
|
|
10
|
+
<p class="sub">
|
|
11
|
+
Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%=size = redis_key_size(params[:id]) %></b>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<h1>Key "<%= params[:id] %>" is a <%= redis_key_type(params[:id]) %></h1>
|
|
15
|
+
<table class="table table-bordered">
|
|
16
|
+
<% redis_get_array(params[:id], start).each do |row| %>
|
|
17
|
+
<tr>
|
|
18
|
+
<td>
|
|
19
|
+
<%= row %>
|
|
20
|
+
</td>
|
|
21
|
+
</tr>
|
|
22
|
+
<% end %>
|
|
23
|
+
</table>
|
|
24
|
+
|
|
25
|
+
<%= pagination :start => start, :total => size %>
|
|
26
|
+
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<h1>Keys owned by <%= Resque %></h1>
|
|
2
|
+
<p class="sub">(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")</p>
|
|
3
|
+
|
|
4
|
+
<table class="table table-bordered stats">
|
|
5
|
+
<tr>
|
|
6
|
+
<th>key</th>
|
|
7
|
+
<th>type</th>
|
|
8
|
+
<th>size</th>
|
|
9
|
+
</tr>
|
|
10
|
+
<% Resque.keys.sort.each do |key| %>
|
|
11
|
+
<tr>
|
|
12
|
+
<th><%= link_to key, statistic_path("keys", key) %></th>
|
|
13
|
+
<td><%= redis_key_type key %></td>
|
|
14
|
+
<td><%= redis_key_size key %></td>
|
|
15
|
+
</tr>
|
|
16
|
+
<% end %>
|
|
17
|
+
</table>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<h1 class="wi">Workers</h1>
|
|
2
|
+
<p class="intro">The hostnames below all have registered workers. Select a hostname to view its workers, or "all" to see all workers.</p>
|
|
3
|
+
|
|
4
|
+
<table class="table table-bordered queues">
|
|
5
|
+
<tr>
|
|
6
|
+
<th>Hostname</th>
|
|
7
|
+
<th>Workers</th>
|
|
8
|
+
</tr>
|
|
9
|
+
<% worker_hosts.each do |hostname, workers| %>
|
|
10
|
+
<tr>
|
|
11
|
+
<td class="queue"><%= link_to hostname, worker_path(hostname), :class => 'queue' %></td>
|
|
12
|
+
<td class="size"><%= workers.size %></td>
|
|
13
|
+
</tr>
|
|
14
|
+
<% end %>
|
|
15
|
+
<tr class="failed">
|
|
16
|
+
<td class="queue failed"><%= link_to "all workers", worker_path('all'), :class => 'queue' %></td>
|
|
17
|
+
<td class="size"><%= Resque.workers.size %></td>
|
|
18
|
+
</tr>
|
|
19
|
+
</table>
|