Skip to content

Commit 2b9eda8

Browse files
authored
Merge pull request #159 from navidemad/feat-compatibility-sidekiq-8
Add Sidekiq 8.0 compatibility while maintaining backward compatibility
2 parents a99e7d1 + 6325225 commit 2b9eda8

File tree

11 files changed

+491
-210
lines changed

11 files changed

+491
-210
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
ruby: [2.6, 2.7, '3.0', 3.1]
16-
sidekiq: [4.2, 5.2, 6.2]
15+
ruby: [2.6, 2.7, '3.0', 3.1, 3.4.3]
16+
sidekiq: [4.2, 5.2, 6.2, 8.0.3]
1717
services:
1818
redis:
1919
image: redis
@@ -27,7 +27,7 @@ jobs:
2727
env:
2828
SIDEKIQ_VERSION: ~> ${{ matrix.sidekiq }}
2929
steps:
30-
- uses: actions/checkout@v3
30+
- uses: actions/checkout@v4
3131
- name: Set up Ruby
3232
uses: ruby/setup-ruby@v1
3333
with:

lib/sidekiq/failures.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ def self.retry_middleware_class
9797
end
9898

9999
if defined?(Sidekiq::Web)
100-
Sidekiq::Web.register Sidekiq::Failures::WebExtension
101-
Sidekiq::Web.tabs["Failures"] = "failures"
102-
Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "failures/locales")
100+
if Sidekiq::Failures::WebExtension.legacy_sidekiq?
101+
Sidekiq::Web.register Sidekiq::Failures::WebExtension
102+
Sidekiq::Web.tabs["Failures"] = "failures"
103+
Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "failures/locales")
104+
else
105+
Sidekiq::Web.configure do |config|
106+
config.locales << File.join(File.dirname(__FILE__), "failures/locales")
107+
config.register(Sidekiq::Failures::WebExtension, name: "failures", tab: ["Failures"], index: ["failures"])
108+
end
109+
end
103110
end

lib/sidekiq/failures/sorted_entry.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def retry_failure
1414
# from Redis v6.2.0, zrangebyscore is deprecated and zrange with BYSCORE is used
1515
# option byscore is available from redis-rb v4.6.0
1616
results = if Gem::Version.new(conn.info["redis_version"].to_s) >= Gem::Version.new('6.2.0') &&
17-
Gem.loaded_specs['redis'].version >= Gem::Version.new('4.6.0')
17+
(Gem.loaded_specs['redis'].nil? || Gem.loaded_specs['redis'].version >= Gem::Version.new('4.6.0'))
1818
conn.zrange(Sidekiq::Failures::LIST_KEY, score.to_i, score.to_i, byscore: true)
1919
else
2020
conn.zrangebyscore(Sidekiq::Failures::LIST_KEY, score, score)
Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
11
<%= erb :_job_info, :locals => {:job => @failure, :type => :failure} %>
22

3-
<h3><%= t('Error') %></h3>
4-
<table class="error table table-bordered table-striped">
5-
<tbody>
6-
<tr>
7-
<th><%= t('ErrorClass') %></th>
8-
<td>
9-
<code><%= h @failure['error_class'] %></code>
10-
</td>
11-
</tr>
12-
<tr>
13-
<th><%= t('ErrorMessage') %></th>
14-
<td><%= h @failure['error_message'] %></td>
15-
</tr>
16-
<% if !@failure['error_backtrace'].nil? %>
17-
<tr>
18-
<th><%= t('ErrorBacktrace') %></th>
19-
<td>
20-
<code><%= @failure['error_backtrace'].join("<br/>") %></code>
21-
</td>
22-
</tr>
23-
<% end %>
24-
</tbody>
25-
</table>
26-
<form class="form-horizontal" action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
27-
<%= csrf_tag if respond_to?(:csrf_tag) %>
28-
<a class="btn" href="<%= root_path %>failures"><%= t('GoBack') %></a>
29-
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
30-
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
31-
</form>
3+
<section>
4+
<header>
5+
<h2><%= t('Error') %></h2>
6+
</header>
7+
8+
<div class="table_container">
9+
<table>
10+
<tbody>
11+
<tr>
12+
<th><%= t('ErrorClass') %></th>
13+
<td>
14+
<code><%= h @failure['error_class'] %></code>
15+
</td>
16+
</tr>
17+
<tr>
18+
<th><%= t('ErrorMessage') %></th>
19+
<td><%= h @failure['error_message'] %></td>
20+
</tr>
21+
<% if !@failure['error_backtrace'].nil? %>
22+
<tr>
23+
<th><%= t('ErrorBacktrace') %></th>
24+
<td>
25+
<code><%= @failure['error_backtrace'].join("<br/>") %></code>
26+
</td>
27+
</tr>
28+
<% end %>
29+
</tbody>
30+
</table>
31+
</div>
32+
33+
<form action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
34+
<%= csrf_tag if respond_to?(:csrf_tag) %>
35+
<a class="btn btn-default" href="<%= root_path %>failures"><%= t('GoBack') %></a>
36+
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
37+
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
38+
</form>
39+
</section>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<%= erb :_job_info, :locals => {:job => @failure, :type => :failure} %>
2+
3+
<h3><%= t('Error') %></h3>
4+
<table class="error table table-bordered table-striped">
5+
<tbody>
6+
<tr>
7+
<th><%= t('ErrorClass') %></th>
8+
<td>
9+
<code><%= h @failure['error_class'] %></code>
10+
</td>
11+
</tr>
12+
<tr>
13+
<th><%= t('ErrorMessage') %></th>
14+
<td><%= h @failure['error_message'] %></td>
15+
</tr>
16+
<% if !@failure['error_backtrace'].nil? %>
17+
<tr>
18+
<th><%= t('ErrorBacktrace') %></th>
19+
<td>
20+
<code><%= @failure['error_backtrace'].join("<br/>") %></code>
21+
</td>
22+
</tr>
23+
<% end %>
24+
</tbody>
25+
</table>
26+
<form class="form-horizontal" action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
27+
<%= csrf_tag if respond_to?(:csrf_tag) %>
28+
<a class="btn" href="<%= root_path %>failures"><%= t('GoBack') %></a>
29+
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
30+
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
31+
</form>
Lines changed: 106 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,113 @@
1-
<header class="row">
2-
<div class="col-sm-5">
3-
<h3><%= t('FailedJobs') %></h3>
4-
</div>
5-
<% if @failures.count > 0 && @total_size > @count %>
6-
<div class="col-sm-4">
1+
<section>
2+
<header>
3+
<h1>
4+
<span class="title"><%= t('FailedJobs') %></span>
5+
<span class="badge badge-secondary"><%= number_with_delimiter(@failures.count) %></span>
6+
</h1>
7+
<% if @failures.count > 0 && @total_size > @count %>
78
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
8-
</div>
9-
<% end %>
10-
<%= filtering('failures') if respond_to?(:filtering) %>
11-
</header>
9+
<% end %>
10+
<%= filtering('failures') if respond_to?(:filtering) %>
11+
</header>
1212

13-
<% if @failures.count > 0 %>
14-
<form action="<%= root_path %>failures" method="post">
15-
<%= csrf_tag if respond_to?(:csrf_tag) %>
16-
<table class="table table-striped table-bordered table-white">
17-
<thead>
18-
<tr>
19-
<th width="20px" class="table-checkbox">
20-
<label>
21-
<input type="checkbox" class="check_all" />
22-
</label>
23-
</th>
24-
<th><%= t('FailedAt') %></th>
25-
<th><%= t('Queue') %></th>
26-
<th><%= t('Worker') %></th>
27-
<th><%= t('Arguments') %></th>
28-
<th><%= t('Error') %></th>
29-
</tr>
30-
</thead>
31-
<% @failures.each do |entry| %>
32-
<tr>
33-
<td class="table-checkbox">
34-
<label>
35-
<input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
36-
</label>
37-
</td>
38-
<td>
39-
<a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= safe_relative_time(entry['failed_at']) %></a>
40-
</td>
41-
<td>
42-
<a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
43-
</td>
44-
<td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
45-
<td>
46-
<div class="args"><%= display_args(entry.respond_to?(:display_args) ? entry.display_args : entry.args) %></div>
47-
</td>
48-
<td style="overflow: auto; padding: 10px;">
49-
<a class="backtrace" href="javascript:void(0)", onclick="toggle_error_backtrace(this)">
50-
<%= h entry['error_class'] %>: <%= h entry['error_message'].to_s.size > 500 ? entry['error_message'][0..500] + '...' : entry['error_message'] %>
51-
</a>
52-
<pre style="display: none; background: none; border: 0; width: 100%; max-height: 30em; font-size: 0.8em; white-space: nowrap; overflow: auto;">
53-
<%= entry['error_backtrace'].join("<br />") if entry['error_backtrace'] %>
54-
</pre>
55-
<p>
56-
<span>Processor: <%= entry['processor'] %></span>
57-
</p>
58-
</td>
59-
</tr>
60-
<% end %>
61-
</table>
62-
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
63-
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
64-
</form>
13+
<% if @failures.count > 0 %>
14+
<form action="<%= root_path %>failures" method="post">
15+
<%= csrf_tag if respond_to?(:csrf_tag) %>
16+
<div class="table_container">
17+
<table>
18+
<thead>
19+
<tr>
20+
<th width="20px" class="table-checkbox">
21+
<label>
22+
<input type="checkbox" class="check_all" />
23+
</label>
24+
</th>
25+
<th><%= t('FailedAt') %></th>
26+
<th><%= t('Queue') %></th>
27+
<th><%= t('Worker') %></th>
28+
<th><%= t('Arguments') %></th>
29+
<th><%= t('Error') %></th>
30+
</tr>
31+
</thead>
32+
<% @failures.each do |entry| %>
33+
<tr>
34+
<td class="table-checkbox">
35+
<label>
36+
<input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
37+
</label>
38+
</td>
39+
<td>
40+
<a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= safe_relative_time(entry['failed_at']) %></a>
41+
</td>
42+
<td>
43+
<a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
44+
</td>
45+
<td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
46+
<td>
47+
<code>
48+
<div class="args"><%= display_args(entry.respond_to?(:display_args) ? entry.display_args : entry.args) %></div>
49+
</code>
50+
</td>
51+
<td>
52+
<% error_class = entry['error_class'].to_s %>
53+
<% error_message = entry['error_message'].to_s %>
54+
<% error_text = "#{h(error_class)}: #{h(error_message)}" %>
55+
<% truncated_error = truncate(error_text, 200) %>
6556

66-
<form action="<%= root_path %>failures/all/delete" method="post">
67-
<%= csrf_tag if respond_to?(:csrf_tag) %>
68-
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
69-
</form>
70-
<form action="<%= root_path %>failures/all/retry" method="post">
71-
<%= csrf_tag if respond_to?(:csrf_tag) %>
72-
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
73-
</form>
57+
<% if entry['error_backtrace'] %>
58+
<details>
59+
<summary>
60+
<%= truncated_error %>
61+
</summary>
62+
<% if entry['error_backtrace'] %>
63+
<code>
64+
<%= entry['error_backtrace'].join("<br/>") %>
65+
</code>
66+
<% end %>
67+
</details>
68+
<% else %>
69+
<div>
70+
<%= truncated_error %>
71+
</div>
72+
<% end %>
73+
<div>
74+
<span>Processor: <%= entry['processor'] %></span>
75+
</div>
76+
</td>
77+
</tr>
78+
<% end %>
79+
</table>
80+
</div>
81+
<div class="buttons-row">
82+
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
83+
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
84+
</div>
85+
</form>
7486

75-
<% if @failures.count > 0 && @total_size > @count %>
76-
<div class="col-sm-4">
77-
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
87+
<div class="buttons-row">
88+
<form action="<%= root_path %>failures/all/delete" method="post">
89+
<%= csrf_tag if respond_to?(:csrf_tag) %>
90+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
91+
</form>
92+
<form action="<%= root_path %>failures/all/retry" method="post">
93+
<%= csrf_tag if respond_to?(:csrf_tag) %>
94+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
95+
</form>
7896
</div>
79-
<% end %>
8097

81-
<script>
82-
function toggle_error_backtrace(e) {
83-
let x = e.nextElementSibling;
84-
if (x.style.display === "none") {
85-
x.style.display = "block";
86-
} else {
87-
x.style.display = "none";
88-
}
89-
}
90-
</script>
98+
<% if @failures.count > 0 && @total_size > @count %>
99+
<div>
100+
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
101+
</div>
102+
<% end %>
103+
<% else %>
104+
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
105+
<% end %>
91106

92-
<style type="text/css">
93-
@media only screen and (prefers-color-scheme: dark) {
94-
pre {
95-
color: white
96-
}
97-
}
98-
</style>
99-
<% else %>
100-
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
101-
<% end %>
102-
<form action="<%= root_path %>failures/all/reset" method="post">
103-
<%= csrf_tag if respond_to?(:csrf_tag) %>
104-
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
105-
</form>
107+
<div class="buttons-row">
108+
<form action="<%= root_path %>failures/all/reset" method="post">
109+
<%= csrf_tag if respond_to?(:csrf_tag) %>
110+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
111+
</form>
112+
</div>
113+
</section>

0 commit comments

Comments
 (0)