sidekiq 6.4.0 → 6.5.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +119 -1
  3. data/README.md +6 -1
  4. data/bin/sidekiq +3 -3
  5. data/bin/sidekiqload +70 -66
  6. data/bin/sidekiqmon +1 -1
  7. data/lib/sidekiq/api.rb +255 -100
  8. data/lib/sidekiq/cli.rb +60 -38
  9. data/lib/sidekiq/client.rb +44 -30
  10. data/lib/sidekiq/component.rb +65 -0
  11. data/lib/sidekiq/delay.rb +2 -2
  12. data/lib/sidekiq/extensions/action_mailer.rb +2 -2
  13. data/lib/sidekiq/extensions/active_record.rb +2 -2
  14. data/lib/sidekiq/extensions/class_methods.rb +2 -2
  15. data/lib/sidekiq/extensions/generic_proxy.rb +3 -3
  16. data/lib/sidekiq/fetch.rb +20 -18
  17. data/lib/sidekiq/job_logger.rb +15 -27
  18. data/lib/sidekiq/job_retry.rb +73 -52
  19. data/lib/sidekiq/job_util.rb +15 -9
  20. data/lib/sidekiq/launcher.rb +58 -54
  21. data/lib/sidekiq/logger.rb +8 -18
  22. data/lib/sidekiq/manager.rb +28 -25
  23. data/lib/sidekiq/metrics/deploy.rb +47 -0
  24. data/lib/sidekiq/metrics/query.rb +153 -0
  25. data/lib/sidekiq/metrics/shared.rb +94 -0
  26. data/lib/sidekiq/metrics/tracking.rb +134 -0
  27. data/lib/sidekiq/middleware/chain.rb +82 -38
  28. data/lib/sidekiq/middleware/current_attributes.rb +18 -12
  29. data/lib/sidekiq/middleware/i18n.rb +6 -4
  30. data/lib/sidekiq/middleware/modules.rb +21 -0
  31. data/lib/sidekiq/monitor.rb +2 -2
  32. data/lib/sidekiq/paginator.rb +17 -9
  33. data/lib/sidekiq/processor.rb +47 -41
  34. data/lib/sidekiq/rails.rb +19 -13
  35. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  36. data/lib/sidekiq/redis_connection.rb +80 -49
  37. data/lib/sidekiq/ring_buffer.rb +29 -0
  38. data/lib/sidekiq/scheduled.rb +53 -24
  39. data/lib/sidekiq/testing/inline.rb +4 -4
  40. data/lib/sidekiq/testing.rb +37 -36
  41. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  42. data/lib/sidekiq/version.rb +1 -1
  43. data/lib/sidekiq/web/action.rb +3 -3
  44. data/lib/sidekiq/web/application.rb +21 -5
  45. data/lib/sidekiq/web/csrf_protection.rb +2 -2
  46. data/lib/sidekiq/web/helpers.rb +21 -8
  47. data/lib/sidekiq/web.rb +8 -4
  48. data/lib/sidekiq/worker.rb +26 -20
  49. data/lib/sidekiq.rb +107 -31
  50. data/sidekiq.gemspec +2 -2
  51. data/web/assets/javascripts/application.js +59 -26
  52. data/web/assets/javascripts/chart.min.js +13 -0
  53. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  54. data/web/assets/javascripts/dashboard.js +0 -17
  55. data/web/assets/javascripts/graph.js +16 -0
  56. data/web/assets/javascripts/metrics.js +262 -0
  57. data/web/assets/stylesheets/application.css +45 -1
  58. data/web/locales/el.yml +43 -19
  59. data/web/locales/en.yml +7 -0
  60. data/web/locales/ja.yml +7 -0
  61. data/web/locales/pt-br.yml +27 -9
  62. data/web/locales/zh-cn.yml +36 -11
  63. data/web/locales/zh-tw.yml +32 -7
  64. data/web/views/_nav.erb +1 -1
  65. data/web/views/_summary.erb +1 -1
  66. data/web/views/busy.erb +9 -4
  67. data/web/views/dashboard.erb +1 -0
  68. data/web/views/metrics.erb +69 -0
  69. data/web/views/metrics_for_job.erb +87 -0
  70. data/web/views/queue.erb +5 -1
  71. metadata +34 -9
  72. data/lib/sidekiq/exception_handler.rb +0 -27
  73. data/lib/sidekiq/util.rb +0 -108
@@ -9,7 +9,7 @@
9
9
  </li>
10
10
  <li class="busy col-sm-1">
11
11
  <a href="<%= root_path %>busy">
12
- <span id="txtBusy" class="count"><%= number_with_delimiter(workers.size) %></span>
12
+ <span id="txtBusy" class="count"><%= number_with_delimiter(workset.size) %></span>
13
13
  <span class="desc"><%= t('Busy') %></span>
14
14
  </a>
15
15
  </li>
data/web/views/busy.erb CHANGED
@@ -15,7 +15,7 @@
15
15
  <p><%= t('Threads') %></p>
16
16
  </div>
17
17
  <div class="stat">
18
- <h3><%= ws = workers.size; number_with_delimiter(ws) %></h3>
18
+ <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
19
19
  <p><%= t('Busy') %></p>
20
20
  </div>
21
21
  <div class="stat">
@@ -48,13 +48,13 @@
48
48
  <thead>
49
49
  <th><%= t('Name') %></th>
50
50
  <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>
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
52
  <th class="col-sm-1"><%= t('Threads') %></th>
53
53
  <th class="col-sm-1"><%= t('Busy') %></th>
54
54
  <th>&nbsp;</th>
55
55
  </thead>
56
56
  <% lead = processes.leader %>
57
- <% processes.each do |process| %>
57
+ <% sorted_processes.each do |process| %>
58
58
  <tr>
59
59
  <td class="box">
60
60
  <%= "#{process['hostname']}:#{process['pid']}" %>
@@ -96,6 +96,11 @@
96
96
  <div class="col-sm-7">
97
97
  <h3><%= t('Jobs') %></h3>
98
98
  </div>
99
+ <% if @workset.size > 0 && @total_size > @count %>
100
+ <div class="col-sm-4">
101
+ <%= erb :_paging, locals: { url: "#{root_path}busy" } %>
102
+ </div>
103
+ <% end %>
99
104
  </div>
100
105
 
101
106
  <div class="table_container">
@@ -109,7 +114,7 @@
109
114
  <th><%= t('Arguments') %></th>
110
115
  <th><%= t('Started') %></th>
111
116
  </thead>
112
- <% workers.each do |process, thread, msg| %>
117
+ <% @workset.each do |process, thread, msg| %>
113
118
  <% job = Sidekiq::JobRecord.new(msg['payload']) %>
114
119
  <tr>
115
120
  <td><%= process %></td>
@@ -1,3 +1,4 @@
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 >
@@ -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/queue.erb CHANGED
@@ -18,6 +18,7 @@
18
18
  <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
19
19
  <th><%= t('Job') %></th>
20
20
  <th><%= t('Arguments') %></th>
21
+ <th><%= t('Context') %></th>
21
22
  <th></th>
22
23
  </thead>
23
24
  <% @jobs.each_with_index do |job, index| %>
@@ -35,12 +36,15 @@
35
36
  <% a = job.display_args %>
36
37
  <% if a.inspect.size > 100 %>
37
38
  <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>
39
+ <button data-toggle="job_<%= index %>_full" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
39
40
  <div class="toggle" id="job_<%= index %>_full"><%= display_args(a) %></div>
40
41
  <% else %>
41
42
  <%= display_args(job.display_args) %>
42
43
  <% end %>
43
44
  </td>
45
+ <td>
46
+ <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
47
+ </td>
44
48
  <td>
45
49
  <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
46
50
  <%= csrf_tag %>
metadata CHANGED
@@ -1,43 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.4.0
4
+ version: 6.5.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2023-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '5'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
- version: 4.2.0
22
+ version: 4.5.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "<"
28
+ - !ruby/object:Gem::Version
29
+ version: '5'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
- version: 4.2.0
32
+ version: 4.5.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: connection_pool
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
37
+ - - "<"
38
+ - !ruby/object:Gem::Version
39
+ version: '3'
31
40
  - - ">="
32
41
  - !ruby/object:Gem::Version
33
- version: 2.2.2
42
+ version: 2.2.5
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '3'
38
50
  - - ">="
39
51
  - !ruby/object:Gem::Version
40
- version: 2.2.2
52
+ version: 2.2.5
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: rack
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -75,8 +87,8 @@ files:
75
87
  - lib/sidekiq/api.rb
76
88
  - lib/sidekiq/cli.rb
77
89
  - lib/sidekiq/client.rb
90
+ - lib/sidekiq/component.rb
78
91
  - lib/sidekiq/delay.rb
79
- - lib/sidekiq/exception_handler.rb
80
92
  - lib/sidekiq/extensions/action_mailer.rb
81
93
  - lib/sidekiq/extensions/active_record.rb
82
94
  - lib/sidekiq/extensions/class_methods.rb
@@ -89,20 +101,27 @@ files:
89
101
  - lib/sidekiq/launcher.rb
90
102
  - lib/sidekiq/logger.rb
91
103
  - lib/sidekiq/manager.rb
104
+ - lib/sidekiq/metrics/deploy.rb
105
+ - lib/sidekiq/metrics/query.rb
106
+ - lib/sidekiq/metrics/shared.rb
107
+ - lib/sidekiq/metrics/tracking.rb
92
108
  - lib/sidekiq/middleware/chain.rb
93
109
  - lib/sidekiq/middleware/current_attributes.rb
94
110
  - lib/sidekiq/middleware/i18n.rb
111
+ - lib/sidekiq/middleware/modules.rb
95
112
  - lib/sidekiq/monitor.rb
96
113
  - lib/sidekiq/paginator.rb
97
114
  - lib/sidekiq/processor.rb
98
115
  - lib/sidekiq/rails.rb
116
+ - lib/sidekiq/redis_client_adapter.rb
99
117
  - lib/sidekiq/redis_connection.rb
118
+ - lib/sidekiq/ring_buffer.rb
100
119
  - lib/sidekiq/scheduled.rb
101
120
  - lib/sidekiq/sd_notify.rb
102
121
  - lib/sidekiq/systemd.rb
103
122
  - lib/sidekiq/testing.rb
104
123
  - lib/sidekiq/testing/inline.rb
105
- - lib/sidekiq/util.rb
124
+ - lib/sidekiq/transaction_aware_client.rb
106
125
  - lib/sidekiq/version.rb
107
126
  - lib/sidekiq/web.rb
108
127
  - lib/sidekiq/web/action.rb
@@ -117,7 +136,11 @@ files:
117
136
  - web/assets/images/logo.png
118
137
  - web/assets/images/status.png
119
138
  - web/assets/javascripts/application.js
139
+ - web/assets/javascripts/chart.min.js
140
+ - web/assets/javascripts/chartjs-plugin-annotation.min.js
120
141
  - web/assets/javascripts/dashboard.js
142
+ - web/assets/javascripts/graph.js
143
+ - web/assets/javascripts/metrics.js
121
144
  - web/assets/stylesheets/application-dark.css
122
145
  - web/assets/stylesheets/application-rtl.css
123
146
  - web/assets/stylesheets/application.css
@@ -162,6 +185,8 @@ files:
162
185
  - web/views/dashboard.erb
163
186
  - web/views/dead.erb
164
187
  - web/views/layout.erb
188
+ - web/views/metrics.erb
189
+ - web/views/metrics_for_job.erb
165
190
  - web/views/morgue.erb
166
191
  - web/views/queue.erb
167
192
  - web/views/queues.erb
@@ -193,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
218
  - !ruby/object:Gem::Version
194
219
  version: '0'
195
220
  requirements: []
196
- rubygems_version: 3.1.4
221
+ rubygems_version: 3.4.20
197
222
  signing_key:
198
223
  specification_version: 4
199
224
  summary: Simple, efficient background processing for Ruby
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "sidekiq"
4
-
5
- module Sidekiq
6
- module ExceptionHandler
7
- class Logger
8
- def call(ex, ctx)
9
- Sidekiq.logger.warn(Sidekiq.dump_json(ctx)) unless ctx.empty?
10
- Sidekiq.logger.warn("#{ex.class.name}: #{ex.message}")
11
- Sidekiq.logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
12
- end
13
-
14
- Sidekiq.error_handlers << Sidekiq::ExceptionHandler::Logger.new
15
- end
16
-
17
- def handle_exception(ex, ctx = {})
18
- Sidekiq.error_handlers.each do |handler|
19
- handler.call(ex, ctx)
20
- rescue => ex
21
- Sidekiq.logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
22
- Sidekiq.logger.error ex
23
- Sidekiq.logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
24
- end
25
- end
26
- end
27
- end
data/lib/sidekiq/util.rb DELETED
@@ -1,108 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "forwardable"
4
- require "socket"
5
- require "securerandom"
6
- require "sidekiq/exception_handler"
7
-
8
- module Sidekiq
9
- ##
10
- # This module is part of Sidekiq core and not intended for extensions.
11
- #
12
-
13
- class RingBuffer
14
- include Enumerable
15
- extend Forwardable
16
- def_delegators :@buf, :[], :each, :size
17
-
18
- def initialize(size, default = 0)
19
- @size = size
20
- @buf = Array.new(size, default)
21
- @index = 0
22
- end
23
-
24
- def <<(element)
25
- @buf[@index % @size] = element
26
- @index += 1
27
- element
28
- end
29
-
30
- def buffer
31
- @buf
32
- end
33
-
34
- def reset(default = 0)
35
- @buf.fill(default)
36
- end
37
- end
38
-
39
- module Util
40
- include ExceptionHandler
41
-
42
- # hack for quicker development / testing environment #2774
43
- PAUSE_TIME = $stdout.tty? ? 0.1 : 0.5
44
-
45
- # Wait for the orblock to be true or the deadline passed.
46
- def wait_for(deadline, &condblock)
47
- remaining = deadline - ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
48
- while remaining > PAUSE_TIME
49
- return if condblock.call
50
- sleep PAUSE_TIME
51
- remaining = deadline - ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
52
- end
53
- end
54
-
55
- def watchdog(last_words)
56
- yield
57
- rescue Exception => ex
58
- handle_exception(ex, {context: last_words})
59
- raise ex
60
- end
61
-
62
- def safe_thread(name, &block)
63
- Thread.new do
64
- Thread.current.name = name
65
- watchdog(name, &block)
66
- end
67
- end
68
-
69
- def logger
70
- Sidekiq.logger
71
- end
72
-
73
- def redis(&block)
74
- Sidekiq.redis(&block)
75
- end
76
-
77
- def tid
78
- Thread.current["sidekiq_tid"] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
79
- end
80
-
81
- def hostname
82
- ENV["DYNO"] || Socket.gethostname
83
- end
84
-
85
- def process_nonce
86
- @@process_nonce ||= SecureRandom.hex(6)
87
- end
88
-
89
- def identity
90
- @@identity ||= "#{hostname}:#{::Process.pid}:#{process_nonce}"
91
- end
92
-
93
- def fire_event(event, options = {})
94
- reverse = options[:reverse]
95
- reraise = options[:reraise]
96
-
97
- arr = Sidekiq.options[:lifecycle_events][event]
98
- arr.reverse! if reverse
99
- arr.each do |block|
100
- block.call
101
- rescue => ex
102
- handle_exception(ex, {context: "Exception during Sidekiq lifecycle event.", event: event})
103
- raise ex if reraise
104
- end
105
- arr.clear
106
- end
107
- end
108
- end