sidekiq 5.2.10 → 6.5.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +391 -1
  3. data/LICENSE +3 -3
  4. data/README.md +24 -35
  5. data/bin/sidekiq +27 -3
  6. data/bin/sidekiqload +79 -67
  7. data/bin/sidekiqmon +8 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +504 -307
  13. data/lib/sidekiq/cli.rb +190 -206
  14. data/lib/sidekiq/client.rb +77 -81
  15. data/lib/sidekiq/component.rb +65 -0
  16. data/lib/sidekiq/delay.rb +8 -7
  17. data/lib/sidekiq/extensions/action_mailer.rb +13 -22
  18. data/lib/sidekiq/extensions/active_record.rb +13 -10
  19. data/lib/sidekiq/extensions/class_methods.rb +14 -11
  20. data/lib/sidekiq/extensions/generic_proxy.rb +7 -5
  21. data/lib/sidekiq/fetch.rb +50 -40
  22. data/lib/sidekiq/job.rb +13 -0
  23. data/lib/sidekiq/job_logger.rb +33 -7
  24. data/lib/sidekiq/job_retry.rb +126 -106
  25. data/lib/sidekiq/job_util.rb +71 -0
  26. data/lib/sidekiq/launcher.rb +177 -83
  27. data/lib/sidekiq/logger.rb +156 -0
  28. data/lib/sidekiq/manager.rb +40 -41
  29. data/lib/sidekiq/metrics/deploy.rb +47 -0
  30. data/lib/sidekiq/metrics/query.rb +153 -0
  31. data/lib/sidekiq/metrics/shared.rb +94 -0
  32. data/lib/sidekiq/metrics/tracking.rb +134 -0
  33. data/lib/sidekiq/middleware/chain.rb +102 -46
  34. data/lib/sidekiq/middleware/current_attributes.rb +63 -0
  35. data/lib/sidekiq/middleware/i18n.rb +7 -7
  36. data/lib/sidekiq/middleware/modules.rb +21 -0
  37. data/lib/sidekiq/monitor.rb +133 -0
  38. data/lib/sidekiq/paginator.rb +20 -16
  39. data/lib/sidekiq/processor.rb +104 -97
  40. data/lib/sidekiq/rails.rb +47 -37
  41. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  42. data/lib/sidekiq/redis_connection.rb +108 -77
  43. data/lib/sidekiq/ring_buffer.rb +29 -0
  44. data/lib/sidekiq/scheduled.rb +64 -35
  45. data/lib/sidekiq/sd_notify.rb +149 -0
  46. data/lib/sidekiq/systemd.rb +24 -0
  47. data/lib/sidekiq/testing/inline.rb +6 -5
  48. data/lib/sidekiq/testing.rb +68 -58
  49. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  50. data/lib/sidekiq/version.rb +2 -1
  51. data/lib/sidekiq/web/action.rb +15 -11
  52. data/lib/sidekiq/web/application.rb +100 -77
  53. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  54. data/lib/sidekiq/web/helpers.rb +134 -94
  55. data/lib/sidekiq/web/router.rb +23 -19
  56. data/lib/sidekiq/web.rb +65 -105
  57. data/lib/sidekiq/worker.rb +253 -106
  58. data/lib/sidekiq.rb +170 -62
  59. data/sidekiq.gemspec +23 -16
  60. data/web/assets/images/apple-touch-icon.png +0 -0
  61. data/web/assets/javascripts/application.js +112 -61
  62. data/web/assets/javascripts/chart.min.js +13 -0
  63. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  64. data/web/assets/javascripts/dashboard.js +53 -89
  65. data/web/assets/javascripts/graph.js +16 -0
  66. data/web/assets/javascripts/metrics.js +262 -0
  67. data/web/assets/stylesheets/application-dark.css +143 -0
  68. data/web/assets/stylesheets/application-rtl.css +0 -4
  69. data/web/assets/stylesheets/application.css +88 -233
  70. data/web/locales/ar.yml +8 -2
  71. data/web/locales/de.yml +14 -2
  72. data/web/locales/el.yml +43 -19
  73. data/web/locales/en.yml +13 -1
  74. data/web/locales/es.yml +18 -2
  75. data/web/locales/fr.yml +10 -3
  76. data/web/locales/ja.yml +7 -1
  77. data/web/locales/lt.yml +83 -0
  78. data/web/locales/pl.yml +4 -4
  79. data/web/locales/pt-br.yml +27 -9
  80. data/web/locales/ru.yml +4 -0
  81. data/web/locales/vi.yml +83 -0
  82. data/web/views/_footer.erb +1 -1
  83. data/web/views/_job_info.erb +3 -2
  84. data/web/views/_nav.erb +1 -1
  85. data/web/views/_poll_link.erb +2 -5
  86. data/web/views/_summary.erb +7 -7
  87. data/web/views/busy.erb +56 -22
  88. data/web/views/dashboard.erb +23 -14
  89. data/web/views/dead.erb +3 -3
  90. data/web/views/layout.erb +3 -1
  91. data/web/views/metrics.erb +69 -0
  92. data/web/views/metrics_for_job.erb +87 -0
  93. data/web/views/morgue.erb +9 -6
  94. data/web/views/queue.erb +23 -10
  95. data/web/views/queues.erb +10 -2
  96. data/web/views/retries.erb +11 -8
  97. data/web/views/retry.erb +3 -3
  98. data/web/views/scheduled.erb +5 -2
  99. metadata +53 -64
  100. data/.circleci/config.yml +0 -61
  101. data/.github/contributing.md +0 -32
  102. data/.github/issue_template.md +0 -11
  103. data/.gitignore +0 -15
  104. data/.travis.yml +0 -11
  105. data/3.0-Upgrade.md +0 -70
  106. data/4.0-Upgrade.md +0 -53
  107. data/5.0-Upgrade.md +0 -56
  108. data/COMM-LICENSE +0 -97
  109. data/Ent-Changes.md +0 -238
  110. data/Gemfile +0 -19
  111. data/Pro-2.0-Upgrade.md +0 -138
  112. data/Pro-3.0-Upgrade.md +0 -44
  113. data/Pro-4.0-Upgrade.md +0 -35
  114. data/Pro-Changes.md +0 -759
  115. data/Rakefile +0 -9
  116. data/bin/sidekiqctl +0 -20
  117. data/code_of_conduct.md +0 -50
  118. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  119. data/lib/sidekiq/core_ext.rb +0 -1
  120. data/lib/sidekiq/ctl.rb +0 -221
  121. data/lib/sidekiq/exception_handler.rb +0 -29
  122. data/lib/sidekiq/logging.rb +0 -122
  123. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
  124. data/lib/sidekiq/util.rb +0 -66
data/web/views/busy.erb CHANGED
@@ -1,8 +1,39 @@
1
1
  <div class="row header">
2
- <div class="col-sm-8 pull-left flip">
2
+ <div class="col-sm-4 pull-left flip">
3
+ <h3><%= t('Status') %></h3>
4
+ </div>
5
+ </div>
6
+
7
+ <div class="stats-wrapper">
8
+ <div class="stats-container">
9
+ <div class="stat">
10
+ <h3><%= s = processes.size; number_with_delimiter(s) %></h3>
11
+ <p><%= t('Processes') %></p>
12
+ </div>
13
+ <div class="stat">
14
+ <h3><%= x = processes.total_concurrency; number_with_delimiter(x) %></h3>
15
+ <p><%= t('Threads') %></p>
16
+ </div>
17
+ <div class="stat">
18
+ <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
19
+ <p><%= t('Busy') %></p>
20
+ </div>
21
+ <div class="stat">
22
+ <h3><%= x == 0 ? 0 : ((ws / x.to_f) * 100).round(0) %>%</h3>
23
+ <p><%= t('Utilization') %></p>
24
+ </div>
25
+ <div class="stat">
26
+ <h3><%= format_memory(processes.total_rss) %></h3>
27
+ <p><%= t('RSS') %></p>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="row header">
33
+ <div class="col-sm-4 pull-left flip">
3
34
  <h3><%= t('Processes') %></h3>
4
35
  </div>
5
- <div class="col-sm-4 pull-right flip">
36
+ <div class="col-sm-3 pull-right flip">
6
37
  <form method="POST" class="warning-messages">
7
38
  <%= csrf_tag %>
8
39
  <div class="btn-group pull-right flip">
@@ -12,18 +43,18 @@
12
43
  </form>
13
44
  </div>
14
45
  </div>
15
-
16
46
  <div class="table_container">
17
- <table class="processes table table-hover table-bordered table-striped table-white">
47
+ <table class="processes table table-hover table-bordered table-striped">
18
48
  <thead>
19
49
  <th><%= t('Name') %></th>
20
50
  <th><%= t('Started') %></th>
21
- <th><%= t('Threads') %></th>
22
- <th><%= t('Busy') %></th>
51
+ <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
52
+ <th class="col-sm-1"><%= t('Threads') %></th>
53
+ <th class="col-sm-1"><%= t('Busy') %></th>
23
54
  <th>&nbsp;</th>
24
55
  </thead>
25
56
  <% lead = processes.leader %>
26
- <% processes.each do |process| %>
57
+ <% sorted_processes.each do |process| %>
27
58
  <tr>
28
59
  <td class="box">
29
60
  <%= "#{process['hostname']}:#{process['pid']}" %>
@@ -39,22 +70,22 @@
39
70
  <% end %>
40
71
  <br>
41
72
  <b><%= "#{t('Queues')}: " %></b>
42
- <%= process['queues'] * ", " %>
73
+ <%= process.queues.join(", ") %>
43
74
  </td>
44
75
  <td><%= relative_time(Time.at(process['started_at'])) %></td>
76
+ <td><%= format_memory(process['rss'].to_i) %></td>
45
77
  <td><%= process['concurrency'] %></td>
46
78
  <td><%= process['busy'] %></td>
47
79
  <td>
48
- <div class="btn-group pull-right flip">
49
- <form method="POST">
50
- <%= csrf_tag %>
51
- <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
52
- <% unless process.stopping? %>
53
- <button class="btn btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button>
54
- <% end %>
55
- <button class="btn btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
56
- </form>
57
- </div>
80
+ <form method="POST">
81
+ <%= csrf_tag %>
82
+ <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
83
+
84
+ <div class="btn-group pull-right flip">
85
+ <% unless process.stopping? %><button class="btn btn-xs btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button><% end %>
86
+ <button class="btn btn-xs btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
87
+ </div>
88
+ </form>
58
89
  </td>
59
90
  </tr>
60
91
  <% end %>
@@ -68,7 +99,7 @@
68
99
  </div>
69
100
 
70
101
  <div class="table_container">
71
- <table class="workers table table-hover table-bordered table-striped table-white">
102
+ <table class="workers table table-hover table-bordered table-striped">
72
103
  <thead>
73
104
  <th><%= t('Process') %></th>
74
105
  <th><%= t('TID') %></th>
@@ -78,8 +109,8 @@
78
109
  <th><%= t('Arguments') %></th>
79
110
  <th><%= t('Started') %></th>
80
111
  </thead>
81
- <% workers.each do |process, thread, msg| %>
82
- <% job = Sidekiq::Job.new(msg['payload']) %>
112
+ <% workset.each do |process, thread, msg| %>
113
+ <% job = Sidekiq::JobRecord.new(msg['payload']) %>
83
114
  <tr>
84
115
  <td><%= process %></td>
85
116
  <td><%= thread %></td>
@@ -87,7 +118,10 @@
87
118
  <td>
88
119
  <a href="<%= root_path %>queues/<%= msg['queue'] %>"><%= msg['queue'] %></a>
89
120
  </td>
90
- <td><%= job.display_class %></td>
121
+ <td>
122
+ <%= job.display_class %>
123
+ <%= display_tags(job, nil) %>
124
+ </td>
91
125
  <td>
92
126
  <div class="args"><%= display_args(job.display_args) %></div>
93
127
  </td>
@@ -1,17 +1,18 @@
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/graph.js"></script>
1
2
  <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
2
3
  <div class= "dashboard clearfix">
3
4
  <h3 >
4
5
  <%= t('Dashboard') %>
5
- <span class="beacon">
6
+ <span id="beacon" class="beacon">
6
7
  <span class="ring"></span>
7
8
  <span class="dot"></span>
8
9
  </span>
9
10
  </h3>
10
11
  <div class="interval-slider ltr">
11
12
  <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
12
- <span class="current-interval">5 sec</span>
13
+ <span id="sldr-text" class="current-interval">5 sec</span>
13
14
  <br/>
14
- <input type="range" min="2000" max="20000" step="1000" value="5000"/>
15
+ <input id="sldr" type="range" min="2000" max="20000" step="1000" value="5000"/>
15
16
  </div>
16
17
  </div>
17
18
 
@@ -20,54 +21,62 @@
20
21
  <div id="realtime-legend"></div>
21
22
  </div>
22
23
 
23
- <div class="row chart">
24
- <h5>
25
- <span class="history-heading"><%= t('History') %></span>
24
+ <div class="row header">
25
+ <div class="col-sm-4 pull-left flip">
26
+ <h3><%= t('History') %></h3>
27
+ </div>
28
+ </div>
29
+ <div class="row chart">
30
+ <div>
26
31
  <a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
27
32
  <a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>"><%= t('OneMonth') %></a>
28
33
  <a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
29
34
  <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
30
- </h5>
35
+ </div>
31
36
 
32
37
  <div id="history" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>" data-processed="<%= h Sidekiq.dump_json(@processed_history) %>" data-failed="<%= h Sidekiq.dump_json(@failed_history) %>" data-update-url="<%= root_path %>stats"></div>
33
38
  <div id="history-legend"></div>
34
39
  </div>
35
40
 
36
41
  <br/>
37
- <h5>Redis</h5>
38
- <div class="redis-wrapper">
42
+ <div class="row header">
43
+ <div class="col-sm-4 pull-left flip">
44
+ <h3>Redis</h3>
45
+ </div>
46
+ </div>
47
+ <div class="stats-wrapper">
39
48
  <div class="stats-container">
40
49
  <% if @redis_info.fetch("redis_version", nil) %>
41
50
  <div class="stat">
42
- <h3 class="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
51
+ <h3 id="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
43
52
  <p><%= t('Version') %></p>
44
53
  </div>
45
54
  <% end %>
46
55
 
47
56
  <% if @redis_info.fetch("uptime_in_days", nil) %>
48
57
  <div class="stat">
49
- <h3 class="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
58
+ <h3 id="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
50
59
  <p><%= t('Uptime') %></p>
51
60
  </div>
52
61
  <% end %>
53
62
 
54
63
  <% if @redis_info.fetch("connected_clients", nil) %>
55
64
  <div class="stat">
56
- <h3 class="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
65
+ <h3 id="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
57
66
  <p><%= t('Connections') %></p>
58
67
  </div>
59
68
  <% end %>
60
69
 
61
70
  <% if @redis_info.fetch("used_memory_human", nil) %>
62
71
  <div class="stat">
63
- <h3 class="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
72
+ <h3 id="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
64
73
  <p><%= t('MemoryUsage') %></p>
65
74
  </div>
66
75
  <% end %>
67
76
 
68
77
  <% if @redis_info.fetch("used_memory_peak_human", nil) %>
69
78
  <div class="stat">
70
- <h3 class="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
79
+ <h3 id="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
71
80
  <p><%= t('PeakMemoryUsage') %></p>
72
81
  </div>
73
82
  <% end %>
data/web/views/dead.erb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <h3><%= t('Error') %></h3>
4
4
  <div class="table_container">
5
- <table class="error table table-bordered table-striped">
5
+ <table class="error table table-bordered table-striped table-hover">
6
6
  <tbody>
7
7
  <tr>
8
8
  <th><%= t('ErrorClass') %></th>
@@ -14,11 +14,11 @@
14
14
  <th><%= t('ErrorMessage') %></th>
15
15
  <td><%= h(@dead['error_message']) %></td>
16
16
  </tr>
17
- <% if !@dead['error_backtrace'].nil? %>
17
+ <% if @dead.error_backtrace %>
18
18
  <tr>
19
19
  <th><%= t('ErrorBacktrace') %></th>
20
20
  <td>
21
- <code><%= @dead['error_backtrace'].join("<br/>") %></code>
21
+ <code><%= @dead.error_backtrace.join("<br/>") %></code>
22
22
  </td>
23
23
  </tr>
24
24
  <% end %>
data/web/views/layout.erb CHANGED
@@ -11,16 +11,18 @@
11
11
  <% end %>
12
12
 
13
13
  <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
14
+ <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" />
14
15
  <% if rtl? %>
15
16
  <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" />
16
17
  <% end %>
17
18
 
19
+ <link rel="apple-touch-icon" href="<%= root_path %>images/apple-touch-icon.png">
18
20
  <link rel="shortcut icon" type="image/ico" href="<%= root_path %>images/favicon.ico" />
19
21
  <script type="text/javascript" src="<%= root_path %>javascripts/application.js"></script>
20
22
  <meta name="google" content="notranslate" />
21
23
  <%= display_custom_head %>
22
24
  </head>
23
- <body class="admin" data-poll-path="<%= poll_path %>" data-locale="<%= locale %>">
25
+ <body class="admin" data-locale="<%= locale %>">
24
26
  <%= erb :_nav %>
25
27
  <div id="page">
26
28
  <div class="container">
@@ -0,0 +1,69 @@
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
+ <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
4
+
5
+ <h2>Total execution time</h2>
6
+
7
+ <%
8
+ table_limit = 20
9
+ chart_limit = 5
10
+ job_results = @query_result.job_results.sort_by { |(kls, jr)| jr.totals["s"] }.reverse.first(table_limit)
11
+ visible_kls = job_results.first(chart_limit).map(&:first)
12
+ %>
13
+
14
+ <canvas id="job-metrics-overview-chart"></canvas>
15
+
16
+ <script>
17
+ window.jobMetricsChart = new JobMetricsOverviewChart(
18
+ "job-metrics-overview-chart",
19
+ <%= Sidekiq.dump_json({
20
+ series: job_results.map { |(kls, jr)| [kls, jr.dig("series", "s")] }.to_h,
21
+ marks: @query_result.marks.map { |m| [m.bucket, m.label] },
22
+ visible: visible_kls,
23
+ labels: @query_result.buckets,
24
+ }) %>
25
+ )
26
+ </script>
27
+
28
+ <h2>Most Time-Consuming Jobs</h2>
29
+
30
+ <div class="table_container">
31
+ <table class="table table-bordered table-striped table-hover">
32
+ <tbody>
33
+ <tr>
34
+ <th><%= t('Name') %></th>
35
+ <th><%= t('Processed') %></th>
36
+ <th><%= t('Failed') %></th>
37
+ <th><%= t('ExecutionTime') %></th>
38
+ <th><%= t('AvgExecutionTime') %></th>
39
+ </tr>
40
+ <% if job_results.any? %>
41
+ <% job_results.each_with_index do |(kls, jr), i| %>
42
+ <tr>
43
+ <td>
44
+ <div class="metrics-swatch-wrapper">
45
+ <% id = "metrics-swatch-#{kls}" %>
46
+ <input
47
+ type="checkbox"
48
+ id="<%= id %>"
49
+ class="metrics-swatch"
50
+ value="<%= kls %>"
51
+ />
52
+ <code><a href="<%= root_path %>metrics/<%= kls %>"><%= kls %></a></code>
53
+ </div>
54
+ <script>jobMetricsChart.registerSwatch("<%= id %>")</script>
55
+ </td>
56
+ <td><%= jr.dig("totals", "p") %></td>
57
+ <td><%= jr.dig("totals", "f") %></td>
58
+ <td><%= jr.dig("totals", "s").round(2) %> seconds</td>
59
+ <td><%= jr.total_avg("s").round(2) %> seconds</td>
60
+ </tr>
61
+ <% end %>
62
+ <% else %>
63
+ <tr><td colspan=5><%= t("NoDataFound") %></td></tr>
64
+ <% end %>
65
+ </tbody>
66
+ </table>
67
+ </div>
68
+
69
+ <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
@@ -0,0 +1,87 @@
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
+ <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
4
+
5
+ <%
6
+ job_result = @query_result.job_results[@name]
7
+ hist_totals = job_result.hist.values.first.zip(*job_result.hist.values[1..-1]).map(&:sum)
8
+ bucket_labels =Sidekiq::Metrics::Histogram::LABELS
9
+ bucket_intervals =Sidekiq::Metrics::Histogram::BUCKET_INTERVALS.reverse
10
+
11
+ # Replace INFINITY since it can't be represented as JSON
12
+ bucket_intervals[0] = bucket_intervals[1] * 2
13
+ %>
14
+
15
+ <% if job_result.totals["s"] > 0 %>
16
+ <div class="header-with-subheader">
17
+ <h1>
18
+ <a href="<%= root_path %>/metrics"><%= t(:metrics).to_s.titleize %></a> /
19
+ <%= h @name %>
20
+ </h1>
21
+ <h2>Histogram summary</h2>
22
+ </div>
23
+
24
+ <canvas id="hist-totals-chart"></canvas>
25
+
26
+ <script>
27
+ window.histTotalsChart = new HistTotalsChart(
28
+ "hist-totals-chart",
29
+ <%= Sidekiq.dump_json({
30
+ series: hist_totals,
31
+ labels: bucket_labels,
32
+ }) %>
33
+ )
34
+ </script>
35
+
36
+ <h2>Performance over time</h2>
37
+
38
+ <canvas id="hist-bubble-chart"></canvas>
39
+
40
+ <script>
41
+ window.histBubbleChart = new HistBubbleChart(
42
+ "hist-bubble-chart",
43
+ <%= Sidekiq.dump_json({
44
+ hist: job_result.hist,
45
+ marks: @query_result.marks.map { |m| [m.bucket, m.label] },
46
+ labels: @query_result.buckets,
47
+ histIntervals: bucket_intervals,
48
+ }) %>
49
+ )
50
+ </script>
51
+
52
+ <div class="table_container">
53
+ <table class="table table-bordered table-striped table-hover">
54
+ <tbody>
55
+ <tr>
56
+ <th><%= t('Time') %></th>
57
+ <th><%= t('Processed') %></th>
58
+ <th><%= t('Failed') %></th>
59
+ <th><%= t('ExecutionTime') %></th>
60
+ <th><%= t('AvgExecutionTime') %></th>
61
+ </tr>
62
+ <% @query_result.buckets.reverse.each do |bucket| %>
63
+ <tr>
64
+ <td><%= bucket %></td>
65
+ <td><%= job_result.series.dig("p", bucket) %></td>
66
+ <td><%= job_result.series.dig("f", bucket) %></td>
67
+ <% if (total_sec = job_result.series.dig("s", bucket)) > 0 %>
68
+ <td><%= total_sec.round(2) %> seconds</td>
69
+ <td><%= job_result.series_avg("s")[bucket].round(2) %> seconds</td>
70
+ <% else %>
71
+ <td>&mdash;</td>
72
+ <td>&mdash;</td>
73
+ <% end %>
74
+ </tr>
75
+ <% end %>
76
+ </tbody>
77
+ </table>
78
+ </div>
79
+ <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
80
+ <% else %>
81
+ <h1>
82
+ <a href="<%= root_path %>/metrics"><%= t(:metrics).to_s.titleize %></a> /
83
+ <%= h @name %>
84
+ </h1>
85
+
86
+ <div class="alert alert-success"><%= t('NoJobMetricsFound') %></div>
87
+ <% end %>
data/web/views/morgue.erb CHANGED
@@ -14,7 +14,7 @@
14
14
  <form action="<%= root_path %>morgue" method="post">
15
15
  <%= csrf_tag %>
16
16
  <div class="table_container">
17
- <table class="table table-striped table-bordered table-white">
17
+ <table class="table table-striped table-bordered table-hover">
18
18
  <thead>
19
19
  <tr>
20
20
  <th class="table-checkbox checkbox-column">
@@ -42,7 +42,10 @@
42
42
  <td>
43
43
  <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
44
44
  </td>
45
- <td><%= entry.display_class %></td>
45
+ <td>
46
+ <%= entry.display_class %>
47
+ <%= display_tags(entry, "dead") %>
48
+ </td>
46
49
  <td>
47
50
  <div class="args"><%= display_args(entry.display_args) %></div>
48
51
  </td>
@@ -55,18 +58,18 @@
55
58
  <% end %>
56
59
  </table>
57
60
  </div>
58
- <input class="btn btn-primary btn-xs pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
59
- <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
61
+ <input class="btn btn-primary pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
62
+ <input class="btn btn-danger pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
60
63
  </form>
61
64
 
62
65
  <% unfiltered? do %>
63
66
  <form action="<%= root_path %>morgue/all/delete" method="post">
64
67
  <%= csrf_tag %>
65
- <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
68
+ <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
66
69
  </form>
67
70
  <form action="<%= root_path %>morgue/all/retry" method="post">
68
71
  <%= csrf_tag %>
69
- <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
72
+ <input class="btn btn-danger pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
70
73
  </form>
71
74
  <% end %>
72
75
 
data/web/views/queue.erb CHANGED
@@ -15,27 +15,40 @@
15
15
  <div class="table_container">
16
16
  <table class="queue table table-hover table-bordered table-striped">
17
17
  <thead>
18
+ <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
18
19
  <th><%= t('Job') %></th>
19
20
  <th><%= t('Arguments') %></th>
21
+ <th><%= t('Context') %></th>
20
22
  <th></th>
21
23
  </thead>
22
- <% @messages.each_with_index do |msg, index| %>
23
- <tr>
24
- <td><%= h(msg.display_class) %></td>
24
+ <% @jobs.each_with_index do |job, index| %>
25
+ <tr title="<%= job.jid %>">
26
+ <% if params[:direction] == 'asc' %>
27
+ <td><%= @count * (@current_page - 1) + index + 1 %></td>
28
+ <% else %>
29
+ <td><%= @total_size - (@count * (@current_page - 1) + index) %></td>
30
+ <% end %>
25
31
  <td>
26
- <% a = msg.display_args %>
32
+ <%= h(job.display_class) %>
33
+ <%= display_tags(job, nil) %>
34
+ </td>
35
+ <td>
36
+ <% a = job.display_args %>
27
37
  <% if a.inspect.size > 100 %>
28
- <span class="worker_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
29
- <button data-toggle="collapse" data-target=".worker_<%= index %>" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
30
- <div class="toggle worker_<%= index %>"><%= display_args(a) %></div>
38
+ <span id="job_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
39
+ <button data-toggle="job_<%= index %>_full" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
40
+ <div class="toggle" id="job_<%= index %>_full"><%= display_args(a) %></div>
31
41
  <% else %>
32
- <%= display_args(msg.display_args) %>
42
+ <%= display_args(job.display_args) %>
33
43
  <% end %>
34
44
  </td>
45
+ <td>
46
+ <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
47
+ </td>
35
48
  <td>
36
49
  <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
37
50
  <%= csrf_tag %>
38
- <input name="key_val" value="<%= h msg.value %>" type="hidden" />
51
+ <input name="key_val" value="<%= h job.value %>" type="hidden" />
39
52
  <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
40
53
  </form>
41
54
  </td>
@@ -43,4 +56,4 @@
43
56
  <% end %>
44
57
  </table>
45
58
  </div>
46
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{@name}" } %>
59
+ <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
data/web/views/queues.erb CHANGED
@@ -1,7 +1,7 @@
1
1
  <h3><%= t('Queues') %></h3>
2
2
 
3
3
  <div class="table_container">
4
- <table class="queues table table-hover table-bordered table-striped table-white">
4
+ <table class="queues table table-hover table-bordered table-striped">
5
5
  <thead>
6
6
  <th><%= t('Queue') %></th>
7
7
  <th><%= t('Size') %></th>
@@ -21,7 +21,15 @@
21
21
  <td class="delete-confirm">
22
22
  <form action="<%=root_path %>queues/<%= CGI.escape(queue.name) %>" method="post">
23
23
  <%= csrf_tag %>
24
- <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
24
+ <input class="btn btn-danger" type="submit" name="delete" title="This will delete all jobs within the queue, it will reappear if you push more jobs to it in the future." value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
25
+
26
+ <% if Sidekiq.pro? %>
27
+ <% if queue.paused? %>
28
+ <input class="btn btn-danger" type="submit" name="unpause" value="<%= t('Unpause') %>" />
29
+ <% else %>
30
+ <input class="btn btn-danger" type="submit" name="pause" value="<%= t('Pause') %>" />
31
+ <% end %>
32
+ <% end %>
25
33
  </form>
26
34
  </td>
27
35
  </tr>
@@ -14,7 +14,7 @@
14
14
  <form action="<%= root_path %>retries" method="post">
15
15
  <%= csrf_tag %>
16
16
  <div class="table_container">
17
- <table class="table table-striped table-bordered table-white">
17
+ <table class="table table-striped table-bordered table-hover">
18
18
  <thead>
19
19
  <tr>
20
20
  <th class="table-checkbox checkbox-column">
@@ -44,7 +44,10 @@
44
44
  <td>
45
45
  <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
46
46
  </td>
47
- <td><%= entry.display_class %></td>
47
+ <td>
48
+ <%= entry.display_class %>
49
+ <%= display_tags(entry, "retries") %>
50
+ </td>
48
51
  <td>
49
52
  <div class="args"><%= display_args(entry.display_args) %></div>
50
53
  </td>
@@ -55,23 +58,23 @@
55
58
  <% end %>
56
59
  </table>
57
60
  </div>
58
- <input class="btn btn-primary btn-xs pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
59
- <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
60
- <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="kill" value="<%= t('Kill') %>" />
61
+ <input class="btn btn-primary pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
62
+ <input class="btn btn-danger pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
63
+ <input class="btn btn-danger pull-left flip" type="submit" name="kill" value="<%= t('Kill') %>" />
61
64
  </form>
62
65
 
63
66
  <% unfiltered? do %>
64
67
  <form action="<%= root_path %>retries/all/delete" method="post">
65
68
  <%= csrf_tag %>
66
- <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
69
+ <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
67
70
  </form>
68
71
  <form action="<%= root_path %>retries/all/retry" method="post">
69
72
  <%= csrf_tag %>
70
- <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
73
+ <input class="btn btn-danger pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
71
74
  </form>
72
75
  <form action="<%= root_path %>retries/all/kill" method="post">
73
76
  <%= csrf_tag %>
74
- <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="kill" value="<%= t('KillAll') %>" data-confirm="<%= t('AreYouSure') %>" />
77
+ <input class="btn btn-danger pull-right flip" type="submit" name="kill" value="<%= t('KillAll') %>" data-confirm="<%= t('AreYouSure') %>" />
75
78
  </form>
76
79
  <% end %>
77
80
 
data/web/views/retry.erb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <h3><%= t('Error') %></h3>
4
4
  <div class="table_container">
5
- <table class="error table table-bordered table-striped">
5
+ <table class="error table table-bordered table-striped table-hover">
6
6
  <tbody>
7
7
  <tr>
8
8
  <th><%= t('ErrorClass') %></th>
@@ -14,11 +14,11 @@
14
14
  <th><%= t('ErrorMessage') %></th>
15
15
  <td><%= h(@retry['error_message']) %></td>
16
16
  </tr>
17
- <% if !@retry['error_backtrace'].nil? %>
17
+ <% if @retry.error_backtrace %>
18
18
  <tr>
19
19
  <th><%= t('ErrorBacktrace') %></th>
20
20
  <td>
21
- <code><%= @retry['error_backtrace'].join("<br/>") %></code>
21
+ <code><%= @retry.error_backtrace.join("<br/>") %></code>
22
22
  </td>
23
23
  </tr>
24
24
  <% end %>