resque-web-edge 1.0.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.
- checksums.yaml +7 -0
- data/README.md +96 -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 +26 -0
- data/app/controllers/resque_web/failures_controller.rb +62 -0
- data/app/controllers/resque_web/jobs_controller.rb +12 -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 +23 -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 +75 -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 +39 -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 +13 -0
- data/config/routes.rb +35 -0
- data/lib/resque_web.rb +4 -0
- data/lib/resque_web/engine.rb +13 -0
- data/lib/resque_web/version.rb +3 -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.ru +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/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/jobs_controller_test.rb +45 -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 +26 -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 +267 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class ApplicationController < ActionController::Base
|
|
3
|
+
include ActionView::Helpers::TextHelper
|
|
4
|
+
protect_from_forgery
|
|
5
|
+
before_filter :set_subtabs, :authorize
|
|
6
|
+
|
|
7
|
+
helper :all
|
|
8
|
+
|
|
9
|
+
def self.subtabs(*tab_names)
|
|
10
|
+
return defined?(@subtabs) ? @subtabs : [] if tab_names.empty?
|
|
11
|
+
@subtabs = tab_names
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def set_subtabs(subtabs = self.class.subtabs)
|
|
15
|
+
@subtabs = subtabs
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def authorize
|
|
21
|
+
if ENV["RESQUE_WEB_HTTP_BASIC_AUTH_USER"] && ENV["RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD"]
|
|
22
|
+
authenticate_or_request_with_http_basic {|u, p| u == ENV["RESQUE_WEB_HTTP_BASIC_AUTH_USER"] && p == ENV["RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD"] }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class FailuresController < ResqueWeb::ApplicationController
|
|
3
|
+
|
|
4
|
+
# Display all jobs in the failure queue
|
|
5
|
+
#
|
|
6
|
+
# @param [Hash] params
|
|
7
|
+
# @option params [String] :class filters failures shown by class
|
|
8
|
+
# @option params [String] :queue filters failures shown by failure queue name
|
|
9
|
+
def index
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# remove an individual job from the failure queue
|
|
13
|
+
def destroy
|
|
14
|
+
Resque::Failure.remove(params[:id])
|
|
15
|
+
redirect_to failures_path(redirect_params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# destroy all jobs from the failure queue
|
|
19
|
+
def destroy_all
|
|
20
|
+
queue = params[:queue] || 'failed'
|
|
21
|
+
Resque::Failure.clear(queue)
|
|
22
|
+
redirect_to failures_path(redirect_params)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# retry an individual job from the failure queue
|
|
26
|
+
def retry
|
|
27
|
+
reque_single_job(params[:id])
|
|
28
|
+
redirect_to failures_path(redirect_params)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# retry all jobs from the failure queue
|
|
32
|
+
def retry_all
|
|
33
|
+
if params[:queue].present? && params[:queue]!="failed"
|
|
34
|
+
Resque::Failure.requeue_queue(params[:queue])
|
|
35
|
+
else
|
|
36
|
+
(Resque::Failure.count-1).downto(0).each { |id| reque_single_job(id) }
|
|
37
|
+
end
|
|
38
|
+
redirect_to failures_path(redirect_params)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
#API agnostic for Resque 2 with duck typing on requeue_and_remove
|
|
44
|
+
def reque_single_job(id)
|
|
45
|
+
if Resque::Failure.respond_to?(:requeue_and_remove)
|
|
46
|
+
Resque::Failure.requeue_and_remove(id)
|
|
47
|
+
else
|
|
48
|
+
Resque::Failure.requeue(id)
|
|
49
|
+
Resque::Failure.remove(id)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def redirect_params
|
|
54
|
+
{}.tap do |p|
|
|
55
|
+
if params[:queue].present?
|
|
56
|
+
p[:queue] = params[:queue]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class JobsController < ApplicationController
|
|
3
|
+
|
|
4
|
+
def destroy
|
|
5
|
+
args = JSON.parse(params[:args])
|
|
6
|
+
destroyed = Resque::Job.destroy(params[:queue], params[:job_class], *args)
|
|
7
|
+
flash[:info] = "#{pluralize(destroyed, 'job')} deleted."
|
|
8
|
+
redirect_to queue_path(params[:queue])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class QueuesController < ResqueWeb::ApplicationController
|
|
3
|
+
|
|
4
|
+
def index
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def show
|
|
8
|
+
set_subtabs view_context.queue_names
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def destroy
|
|
12
|
+
Resque.remove_queue(params[:id])
|
|
13
|
+
redirect_to queues_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def clear
|
|
17
|
+
Resque.redis.del("queue:#{params[:id]}")
|
|
18
|
+
redirect_to queue_path(params[:id])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class StatsController < ResqueWeb::ApplicationController
|
|
3
|
+
subtabs :resque, :redis, :keys
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
redirect_to action: "resque"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def resque
|
|
10
|
+
respond_to do |format|
|
|
11
|
+
format.html
|
|
12
|
+
format.json { render json: Hash[Resque.info.sort] }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def redis
|
|
17
|
+
respond_to do |format|
|
|
18
|
+
format.html
|
|
19
|
+
format.json { render json: Hash[Resque.redis.info.sort] }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def keys
|
|
24
|
+
respond_to do |format|
|
|
25
|
+
format.html do
|
|
26
|
+
if params[:id]
|
|
27
|
+
render 'key'
|
|
28
|
+
else
|
|
29
|
+
render 'keys'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
format.json { render json: Resque.keys.sort }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module ResqueWeb
|
|
2
|
+
class WorkersController < ResqueWeb::ApplicationController
|
|
3
|
+
before_filter :display_subtabs
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def show
|
|
9
|
+
if params[:id] && params[:id] != 'all'
|
|
10
|
+
@workers = view_context.worker_hosts[params[:id]].map { |id| Resque::Worker.find(id) }
|
|
11
|
+
else
|
|
12
|
+
@workers = Resque.workers
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def display_subtabs
|
|
19
|
+
set_subtabs view_context.worker_hosts.map(&:first)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -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
|
+
request.path.starts_with? tabs[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
|