sidekiq 6.3.1 → 7.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +285 -11
  3. data/LICENSE.txt +9 -0
  4. data/README.md +47 -34
  5. data/bin/sidekiq +4 -9
  6. data/bin/sidekiqload +207 -117
  7. data/bin/sidekiqmon +4 -1
  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 +333 -190
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +86 -80
  15. data/lib/sidekiq/client.rb +104 -95
  16. data/lib/sidekiq/{util.rb → component.rb} +14 -41
  17. data/lib/sidekiq/config.rb +282 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +23 -24
  21. data/lib/sidekiq/job.rb +371 -10
  22. data/lib/sidekiq/job_logger.rb +16 -28
  23. data/lib/sidekiq/job_retry.rb +99 -58
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +103 -95
  26. data/lib/sidekiq/logger.rb +9 -44
  27. data/lib/sidekiq/manager.rb +40 -41
  28. data/lib/sidekiq/metrics/query.rb +153 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +96 -51
  32. data/lib/sidekiq/middleware/current_attributes.rb +59 -16
  33. data/lib/sidekiq/middleware/i18n.rb +6 -4
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +17 -4
  36. data/lib/sidekiq/paginator.rb +17 -9
  37. data/lib/sidekiq/processor.rb +81 -80
  38. data/lib/sidekiq/rails.rb +21 -14
  39. data/lib/sidekiq/redis_client_adapter.rb +95 -0
  40. data/lib/sidekiq/redis_connection.rb +14 -82
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +76 -38
  43. data/lib/sidekiq/testing/inline.rb +4 -4
  44. data/lib/sidekiq/testing.rb +42 -69
  45. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  46. data/lib/sidekiq/version.rb +2 -1
  47. data/lib/sidekiq/web/action.rb +3 -3
  48. data/lib/sidekiq/web/application.rb +95 -11
  49. data/lib/sidekiq/web/csrf_protection.rb +4 -4
  50. data/lib/sidekiq/web/helpers.rb +58 -30
  51. data/lib/sidekiq/web.rb +22 -17
  52. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  53. data/lib/sidekiq.rb +85 -202
  54. data/sidekiq.gemspec +12 -10
  55. data/web/assets/javascripts/application.js +77 -26
  56. data/web/assets/javascripts/base-charts.js +106 -0
  57. data/web/assets/javascripts/chart.min.js +13 -0
  58. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  59. data/web/assets/javascripts/dashboard-charts.js +168 -0
  60. data/web/assets/javascripts/dashboard.js +3 -240
  61. data/web/assets/javascripts/metrics.js +264 -0
  62. data/web/assets/stylesheets/application-dark.css +17 -17
  63. data/web/assets/stylesheets/application-rtl.css +2 -91
  64. data/web/assets/stylesheets/application.css +69 -302
  65. data/web/locales/ar.yml +70 -70
  66. data/web/locales/cs.yml +62 -62
  67. data/web/locales/da.yml +60 -53
  68. data/web/locales/de.yml +65 -65
  69. data/web/locales/el.yml +43 -24
  70. data/web/locales/en.yml +84 -69
  71. data/web/locales/es.yml +68 -68
  72. data/web/locales/fa.yml +65 -65
  73. data/web/locales/fr.yml +81 -67
  74. data/web/locales/gd.yml +99 -0
  75. data/web/locales/he.yml +65 -64
  76. data/web/locales/hi.yml +59 -59
  77. data/web/locales/it.yml +53 -53
  78. data/web/locales/ja.yml +73 -68
  79. data/web/locales/ko.yml +52 -52
  80. data/web/locales/lt.yml +66 -66
  81. data/web/locales/nb.yml +61 -61
  82. data/web/locales/nl.yml +52 -52
  83. data/web/locales/pl.yml +45 -45
  84. data/web/locales/pt-br.yml +83 -55
  85. data/web/locales/pt.yml +51 -51
  86. data/web/locales/ru.yml +67 -66
  87. data/web/locales/sv.yml +53 -53
  88. data/web/locales/ta.yml +60 -60
  89. data/web/locales/uk.yml +62 -61
  90. data/web/locales/ur.yml +64 -64
  91. data/web/locales/vi.yml +67 -67
  92. data/web/locales/zh-cn.yml +43 -16
  93. data/web/locales/zh-tw.yml +42 -8
  94. data/web/views/_footer.erb +5 -2
  95. data/web/views/_job_info.erb +18 -2
  96. data/web/views/_metrics_period_select.erb +12 -0
  97. data/web/views/_nav.erb +1 -1
  98. data/web/views/_paging.erb +2 -0
  99. data/web/views/_poll_link.erb +1 -1
  100. data/web/views/_summary.erb +1 -1
  101. data/web/views/busy.erb +44 -28
  102. data/web/views/dashboard.erb +36 -4
  103. data/web/views/filtering.erb +7 -0
  104. data/web/views/metrics.erb +82 -0
  105. data/web/views/metrics_for_job.erb +68 -0
  106. data/web/views/morgue.erb +5 -9
  107. data/web/views/queue.erb +15 -15
  108. data/web/views/queues.erb +3 -1
  109. data/web/views/retries.erb +5 -9
  110. data/web/views/scheduled.erb +12 -13
  111. metadata +62 -31
  112. data/LICENSE +0 -9
  113. data/lib/generators/sidekiq/worker_generator.rb +0 -57
  114. data/lib/sidekiq/delay.rb +0 -41
  115. data/lib/sidekiq/exception_handler.rb +0 -27
  116. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  117. data/lib/sidekiq/extensions/active_record.rb +0 -43
  118. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  119. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  120. data/lib/sidekiq/worker.rb +0 -311
data/web/views/busy.erb CHANGED
@@ -1,7 +1,5 @@
1
- <div class="row header">
2
- <div class="col-sm-4 pull-left flip">
3
- <h3><%= t('Status') %></h3>
4
- </div>
1
+ <div class="header-container">
2
+ <h1><%= t('Status') %></h1>
5
3
  </div>
6
4
 
7
5
  <div class="stats-wrapper">
@@ -15,7 +13,7 @@
15
13
  <p><%= t('Threads') %></p>
16
14
  </div>
17
15
  <div class="stat">
18
- <h3><%= ws = workers.size; number_with_delimiter(ws) %></h3>
16
+ <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
19
17
  <p><%= t('Busy') %></p>
20
18
  </div>
21
19
  <div class="stat">
@@ -29,32 +27,31 @@
29
27
  </div>
30
28
  </div>
31
29
 
32
- <div class="row header">
33
- <div class="col-sm-4 pull-left flip">
34
- <h3><%= t('Processes') %></h3>
35
- </div>
36
- <div class="col-sm-3 pull-right flip">
30
+ <div class="header-container">
31
+ <h1><%= t('Processes') %></h1>
32
+ <div>
37
33
  <form method="POST" class="warning-messages">
38
34
  <%= csrf_tag %>
39
35
  <div class="btn-group pull-right flip">
40
- <button class="btn btn-warn" type="submit" name="quiet" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('QuietAll') %></button>
41
- <button class="btn btn-danger" type="submit" name="stop" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('StopAll') %></button>
36
+ <input class="btn btn-warn" type="submit" name="quiet" value="<%= t('QuietAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
37
+ <input class="btn btn-danger" type="submit" name="stop" value="<%= t('StopAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
42
38
  </div>
43
39
  </form>
44
40
  </div>
45
41
  </div>
42
+
46
43
  <div class="table_container">
47
44
  <table class="processes table table-hover table-bordered table-striped">
48
45
  <thead>
49
46
  <th><%= t('Name') %></th>
50
47
  <th><%= t('Started') %></th>
51
- <th class="col-sm-1"><%= t('RSS') %><a href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
48
+ <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
52
49
  <th class="col-sm-1"><%= t('Threads') %></th>
53
50
  <th class="col-sm-1"><%= t('Busy') %></th>
54
51
  <th>&nbsp;</th>
55
52
  </thead>
56
53
  <% lead = processes.leader %>
57
- <% processes.each do |process| %>
54
+ <% sorted_processes.each do |process| %>
58
55
  <tr>
59
56
  <td class="box">
60
57
  <%= "#{process['hostname']}:#{process['pid']}" %>
@@ -62,6 +59,9 @@
62
59
  <% process.labels.each do |label| %>
63
60
  <span class="label label-info"><%= label %></span>
64
61
  <% end %>
62
+ <% if process.embedded? %>
63
+ <span class="label label-default">embedded</span>
64
+ <% end %>
65
65
  <% if process.stopping? %>
66
66
  <span class="label label-danger">quiet</span>
67
67
  <% end %>
@@ -70,32 +70,48 @@
70
70
  <% end %>
71
71
  <br>
72
72
  <b><%= "#{t('Queues')}: " %></b>
73
- <%= process.queues.join(", ") %>
73
+ <% if process.weights %>
74
+ <%= busy_weights(process.weights) %>
75
+ <% else %>
76
+ <%= process.queues.sort.join(", ") %>
77
+ <% end %>
78
+ <% if process.version != Sidekiq::VERSION %>
79
+ <br>
80
+ <b><%= "#{t('Version')}: " %></b>
81
+ <% if process.version %>
82
+ <%= process.version %>
83
+ <% else %>
84
+ <%= t('Unknown') %>
85
+ <% end %>
86
+ <% end %>
74
87
  </td>
75
88
  <td><%= relative_time(Time.at(process['started_at'])) %></td>
76
89
  <td><%= format_memory(process['rss'].to_i) %></td>
77
90
  <td><%= process['concurrency'] %></td>
78
91
  <td><%= process['busy'] %></td>
79
92
  <td>
80
- <form method="POST">
81
- <%= csrf_tag %>
82
- <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
93
+ <% unless process.embedded? %>
94
+ <form method="POST">
95
+ <%= csrf_tag %>
96
+ <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
83
97
 
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>
98
+ <div class="btn-group pull-right flip">
99
+ <% unless process.stopping? %><button class="btn btn-xs btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button><% end %>
100
+ <button class="btn btn-xs btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
101
+ </div>
102
+ </form>
103
+ <% end %>
89
104
  </td>
90
105
  </tr>
91
106
  <% end %>
92
107
  </table>
93
108
  </div>
94
109
 
95
- <div class="row header">
96
- <div class="col-sm-7">
97
- <h3><%= t('Jobs') %></h3>
98
- </div>
110
+ <div class="header-container">
111
+ <h1><%= t('Jobs') %></h1>
112
+ <% if @workset.size > 0 && @total_size > @count %>
113
+ <%= erb :_paging, locals: { url: "#{root_path}busy" } %>
114
+ <% end %>
99
115
  </div>
100
116
 
101
117
  <div class="table_container">
@@ -109,7 +125,7 @@
109
125
  <th><%= t('Arguments') %></th>
110
126
  <th><%= t('Started') %></th>
111
127
  </thead>
112
- <% workers.each do |process, thread, msg| %>
128
+ <% @workset.each do |process, thread, msg| %>
113
129
  <% job = Sidekiq::JobRecord.new(msg['payload']) %>
114
130
  <tr>
115
131
  <td><%= process %></td>
@@ -1,3 +1,7 @@
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/base-charts.js"></script>
4
+ <script type="text/javascript" src="<%= root_path %>javascripts/dashboard-charts.js"></script>
1
5
  <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
2
6
  <div class= "dashboard clearfix">
3
7
  <h3 >
@@ -16,8 +20,26 @@
16
20
  </div>
17
21
 
18
22
  <div class="row chart">
19
- <div id="realtime" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>"></div>
20
- <div id="realtime-legend"></div>
23
+ <canvas id="realtime-chart"></canvas>
24
+ <script>
25
+ window.realtimeChart = new RealtimeChart(
26
+ document.getElementById("realtime-chart"),
27
+ <%= Sidekiq.dump_json({
28
+ processedLabel: t('Processed'),
29
+ failedLabel: t('Failed'),
30
+ labels: Array.new(50, ""),
31
+ processed: Array.new(50),
32
+ failed: Array.new(50),
33
+ updateUrl: "#{root_path}stats",
34
+ }) %>
35
+ )
36
+ </script>
37
+
38
+ <!-- start with a space in the legend so the height doesn't change when we add content dynamically -->
39
+ <div id="realtime-legend">&nbsp;</div>
40
+ <script>
41
+ realtimeChart.registerLegend(document.getElementById("realtime-legend"))
42
+ </script>
21
43
  </div>
22
44
 
23
45
  <div class="row header">
@@ -33,8 +55,18 @@
33
55
  <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
34
56
  </div>
35
57
 
36
- <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>
37
- <div id="history-legend"></div>
58
+ <canvas id="history-chart"></canvas>
59
+ <script>
60
+ window.historyChart = new DashboardChart(
61
+ document.getElementById("history-chart"),
62
+ <%= Sidekiq.dump_json({
63
+ processedLabel: t('Processed'),
64
+ failedLabel: t('Failed'),
65
+ processed: @processed_history.to_a.reverse,
66
+ failed: @failed_history.to_a.reverse,
67
+ }) %>
68
+ )
69
+ </script>
38
70
  </div>
39
71
 
40
72
  <br/>
@@ -0,0 +1,7 @@
1
+ <div class="sm-col-3 pull-right" style="display: inline; margin: 25px 15px 0 0;">
2
+ <%= t('Filter') %>:
3
+ <form method="POST" action='<%= root_path %>filter/<%= which %>' style="display: inline-block">
4
+ <%= csrf_tag %>
5
+ <input class="search" type="search" name="substr" value="<%= h params[:substr] %>" placeholder="<%= t('AnyJobContent') %>"/>
6
+ </form>
7
+ </div>
@@ -0,0 +1,82 @@
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/base-charts.js"></script>
4
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
5
+
6
+ <div class="header-container">
7
+ <div class="page-title-container">
8
+ <h1><%= t('Metrics') %></h1>
9
+
10
+ <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
11
+ </div>
12
+
13
+ <%= erb :_metrics_period_select, locals: { periods: @periods, period: @period, path: "#{root_path}metrics" } %>
14
+ </div>
15
+
16
+ <%
17
+ table_limit = 20
18
+ chart_limit = 5
19
+ job_results = @query_result.job_results.sort_by { |(kls, jr)| jr.totals["s"] }.reverse.first(table_limit)
20
+ visible_kls = job_results.first(chart_limit).map(&:first)
21
+ %>
22
+
23
+ <% if job_results.any? %>
24
+ <canvas id="job-metrics-overview-chart"></canvas>
25
+
26
+ <script>
27
+ window.jobMetricsChart = new JobMetricsOverviewChart(
28
+ document.getElementById("job-metrics-overview-chart"),
29
+ <%= Sidekiq.dump_json({
30
+ series: job_results.map { |(kls, jr)| [kls, jr.dig("series", "s")] }.to_h,
31
+ marks: @query_result.marks.map { |m| [m.bucket, m.label] },
32
+ labels: @query_result.buckets,
33
+ visibleKls: visible_kls,
34
+ yLabel: t('TotalExecutionTime'),
35
+ units: t('Seconds').downcase,
36
+ markLabel: t('Deploy'),
37
+ }) %>
38
+ )
39
+ </script>
40
+ <% end %>
41
+
42
+ <div class="table_container">
43
+ <table class="table table-bordered table-striped table-hover">
44
+ <tbody>
45
+ <tr>
46
+ <th><%= t('Name') %></th>
47
+ <th><%= t('Success') %></th>
48
+ <th><%= t('Failure') %></th>
49
+ <th><%= t('TotalExecutionTime') %></th>
50
+ <th><%= t('AvgExecutionTime') %></th>
51
+ </tr>
52
+ <% if job_results.any? %>
53
+ <% job_results.each_with_index do |(kls, jr), i| %>
54
+ <tr>
55
+ <td>
56
+ <div class="metrics-swatch-wrapper">
57
+ <% id = "metrics-swatch-#{kls}" %>
58
+ <input
59
+ type="checkbox"
60
+ id="<%= id %>"
61
+ class="metrics-swatch"
62
+ value="<%= kls %>"
63
+ <%= visible_kls.include?(kls) ? 'checked' : '' %>
64
+ />
65
+ <code><a href="<%= root_path %>metrics/<%= kls %>?period=<%= @period %>"><%= kls %></a></code>
66
+ </div>
67
+ <script>jobMetricsChart.registerSwatch("<%= id %>")</script>
68
+ </td>
69
+ <td><%= jr.dig("totals", "p") - jr.dig("totals", "f") %></td>
70
+ <td><%= jr.dig("totals", "f") %></td>
71
+ <td><%= jr.dig("totals", "s").round(2) %> seconds</td>
72
+ <td><%= jr.total_avg("s").round(2) %> seconds</td>
73
+ </tr>
74
+ <% end %>
75
+ <% else %>
76
+ <tr><td colspan=5><%= t("NoDataFound") %></td></tr>
77
+ <% end %>
78
+ </tbody>
79
+ </table>
80
+ </div>
81
+
82
+ <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
@@ -0,0 +1,68 @@
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/base-charts.js"></script>
4
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
5
+
6
+ <%
7
+ job_result = @query_result.job_results[@name]
8
+ hist_totals = job_result.hist.values.first.zip(*job_result.hist.values[1..-1]).map(&:sum).reverse
9
+ bucket_labels = Sidekiq::Metrics::Histogram::LABELS
10
+ bucket_intervals = Sidekiq::Metrics::Histogram::BUCKET_INTERVALS
11
+ %>
12
+
13
+ <% if job_result.totals["s"] > 0 %>
14
+ <div class="header-container">
15
+ <div class="page-title-container">
16
+ <h1>
17
+ <a href="<%= root_path %>metrics?period=<%= @period %>"><%= t('Metrics') %></a> /
18
+ <%= h @name %>
19
+ </h1>
20
+
21
+ <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
22
+ </div>
23
+
24
+ <%= erb :_metrics_period_select, locals: { periods: @periods, period: @period, path: "#{root_path}metrics/#{@name}" } %>
25
+ </div>
26
+
27
+ <canvas id="hist-totals-chart"></canvas>
28
+
29
+ <script>
30
+ window.histTotalsChart = new HistTotalsChart(
31
+ document.getElementById("hist-totals-chart"),
32
+ <%= Sidekiq.dump_json({
33
+ series: hist_totals,
34
+ labels: bucket_labels,
35
+ xLabel: t('ExecutionTime'),
36
+ yLabel: t('Jobs'),
37
+ units: t('Jobs').downcase,
38
+ }) %>
39
+ )
40
+ </script>
41
+
42
+ <canvas id="hist-bubble-chart"></canvas>
43
+
44
+ <script>
45
+ window.histBubbleChart = new HistBubbleChart(
46
+ document.getElementById("hist-bubble-chart"),
47
+ <%= Sidekiq.dump_json({
48
+ hist: job_result.hist,
49
+ marks: @query_result.marks.map { |m| [m.bucket, m.label] },
50
+ labels: @query_result.buckets,
51
+ histIntervals: bucket_intervals,
52
+ yLabel: t('ExecutionTime'),
53
+ markLabel: t('Deploy'),
54
+ yUnits: t('Seconds').downcase,
55
+ zUnits: t('Jobs').downcase,
56
+ }) %>
57
+ )
58
+ </script>
59
+
60
+ <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
61
+ <% else %>
62
+ <h1>
63
+ <a href="<%= root_path %>/metrics"><%= t('Metrics') %></a> /
64
+ <%= h @name %>
65
+ </h1>
66
+
67
+ <div class="alert alert-success"><%= t('NoJobMetricsFound') %></div>
68
+ <% end %>
data/web/views/morgue.erb CHANGED
@@ -1,14 +1,10 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3><%= t('DeadJobs') %></h3>
4
- </div>
1
+ <div class="header-container">
2
+ <h1><%= t('DeadJobs') %></h1>
5
3
  <% if @dead.size > 0 && @total_size > @count %>
6
- <div class="col-sm-4">
7
- <%= erb :_paging, locals: { url: "#{root_path}morgue" } %>
8
- </div>
4
+ <%= erb :_paging, locals: { url: "#{root_path}morgue" } %>
9
5
  <% end %>
10
6
  <%= filtering('dead') %>
11
- </header>
7
+ </div>
12
8
 
13
9
  <% if @dead.size > 0 %>
14
10
  <form action="<%= root_path %>morgue" method="post">
@@ -33,7 +29,7 @@
33
29
  <tr>
34
30
  <td class="table-checkbox">
35
31
  <label>
36
- <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
32
+ <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' class='shift_clickable' />
37
33
  </label>
38
34
  </td>
39
35
  <td>
data/web/views/queue.erb CHANGED
@@ -1,23 +1,20 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3>
4
- <%= t('CurrentMessagesInQueue', :queue => h(@name)) %>
5
- <% if @queue.paused? %>
6
- <span class="label label-danger"><%= t('Paused') %></span>
7
- <% end %>
8
- <span class="badge badge-secondary"><%= number_with_delimiter(@total_size) %></span>
9
- </h3>
10
- </div>
11
- <div class="col-sm-4 pull-right flip">
12
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
13
- </div>
14
- </header>
1
+ <div class="header-container">
2
+ <h1><%= t('CurrentMessagesInQueue', :queue => h(@name)) %>
3
+ <% if @queue.paused? %>
4
+ <span class="label label-danger"><%= t('Paused') %></span>
5
+ <% end %>
6
+ <span class="badge badge-secondary"><%= number_with_delimiter(@total_size) %></span>
7
+ </h1>
8
+ <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
9
+ </div>
10
+
15
11
  <div class="table_container">
16
12
  <table class="queue table table-hover table-bordered table-striped">
17
13
  <thead>
18
14
  <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
19
15
  <th><%= t('Job') %></th>
20
16
  <th><%= t('Arguments') %></th>
17
+ <th><%= t('Context') %></th>
21
18
  <th></th>
22
19
  </thead>
23
20
  <% @jobs.each_with_index do |job, index| %>
@@ -35,12 +32,15 @@
35
32
  <% a = job.display_args %>
36
33
  <% if a.inspect.size > 100 %>
37
34
  <span id="job_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
38
- <button data-toggle="job_<%= index %>" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
35
+ <button data-toggle="job_<%= index %>_full" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
39
36
  <div class="toggle" id="job_<%= index %>_full"><%= display_args(a) %></div>
40
37
  <% else %>
41
38
  <%= display_args(job.display_args) %>
42
39
  <% end %>
43
40
  </td>
41
+ <td>
42
+ <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
43
+ </td>
44
44
  <td>
45
45
  <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
46
46
  <%= csrf_tag %>
data/web/views/queues.erb CHANGED
@@ -1,4 +1,6 @@
1
- <h3><%= t('Queues') %></h3>
1
+ <div class="header-container">
2
+ <h1><%= t('Queues') %></h1>
3
+ </div>
2
4
 
3
5
  <div class="table_container">
4
6
  <table class="queues table table-hover table-bordered table-striped">
@@ -1,14 +1,10 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3><%= t('Retries') %></h3>
4
- </div>
1
+ <div class="header-container">
2
+ <h1><%= t('Retries') %></h1>
5
3
  <% if @retries.size > 0 && @total_size > @count %>
6
- <div class="col-sm-4">
7
- <%= erb :_paging, locals: { url: "#{root_path}retries" } %>
8
- </div>
4
+ <%= erb :_paging, locals: { url: "#{root_path}retries" } %>
9
5
  <% end %>
10
6
  <%= filtering('retries') %>
11
- </header>
7
+ </div>
12
8
 
13
9
  <% if @retries.size > 0 %>
14
10
  <form action="<%= root_path %>retries" method="post">
@@ -34,7 +30,7 @@
34
30
  <tr>
35
31
  <td class="table-checkbox">
36
32
  <label>
37
- <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
33
+ <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' class='shift_clickable' />
38
34
  </label>
39
35
  </td>
40
36
  <td>
@@ -1,25 +1,22 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3><%= t('ScheduledJobs') %></h3>
4
- </div>
1
+ <div class="header-container">
2
+ <h1><%= t('ScheduledJobs') %></h1>
5
3
  <% if @scheduled.size > 0 && @total_size > @count %>
6
- <div class="col-sm-4">
7
- <%= erb :_paging, locals: { url: "#{root_path}scheduled" } %>
8
- </div>
4
+ <%= erb :_paging, locals: { url: "#{root_path}scheduled" } %>
9
5
  <% end %>
10
6
  <%= filtering('scheduled') %>
11
- </header>
7
+ </div>
12
8
 
13
9
  <% if @scheduled.size > 0 %>
14
-
15
10
  <form action="<%= root_path %>scheduled" method="post">
16
11
  <%= csrf_tag %>
17
12
  <div class="table_container">
18
13
  <table class="table table-striped table-bordered table-hover">
19
14
  <thead>
20
15
  <tr>
21
- <th class="checkbox-column">
22
- <input type="checkbox" class="check_all" />
16
+ <th class="table-checkbox checkbox-column">
17
+ <label>
18
+ <input type="checkbox" class="check_all" />
19
+ </label>
23
20
  </th>
24
21
  <th><%= t('When') %></th>
25
22
  <th><%= t('Queue') %></th>
@@ -29,8 +26,10 @@
29
26
  </thead>
30
27
  <% @scheduled.each do |entry| %>
31
28
  <tr>
32
- <td>
33
- <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
29
+ <td class="table-checkbox">
30
+ <label>
31
+ <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' class='shift_clickable' />
32
+ </label>
34
33
  </td>
35
34
  <td>
36
35
  <a href="<%= root_path %>scheduled/<%= job_params(entry.item, entry.score) %>"><%= relative_time(entry.at) %></a>