sidekiq 6.3.1 → 6.4.1

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.

@@ -171,6 +171,8 @@ module Sidekiq
171
171
  # SomeWorker.set(queue: 'foo').perform_async(....)
172
172
  #
173
173
  class Setter
174
+ include Sidekiq::JobUtil
175
+
174
176
  def initialize(klass, opts)
175
177
  @klass = klass
176
178
  @opts = opts
@@ -188,13 +190,59 @@ module Sidekiq
188
190
  end
189
191
 
190
192
  def perform_async(*args)
191
- @klass.client_push(@opts.merge("args" => args, "class" => @klass))
193
+ if @opts["sync"] == true
194
+ perform_inline(*args)
195
+ else
196
+ @klass.client_push(@opts.merge("args" => args, "class" => @klass))
197
+ end
198
+ end
199
+
200
+ # Explicit inline execution of a job. Returns nil if the job did not
201
+ # execute, true otherwise.
202
+ def perform_inline(*args)
203
+ raw = @opts.merge("args" => args, "class" => @klass).transform_keys(&:to_s)
204
+
205
+ # validate and normalize payload
206
+ item = normalize_item(raw)
207
+ queue = item["queue"]
208
+
209
+ # run client-side middleware
210
+ result = Sidekiq.client_middleware.invoke(item["class"], item, queue, Sidekiq.redis_pool) do
211
+ item
212
+ end
213
+ return nil unless result
214
+
215
+ # round-trip the payload via JSON
216
+ msg = Sidekiq.load_json(Sidekiq.dump_json(item))
217
+
218
+ # prepare the job instance
219
+ klass = msg["class"].constantize
220
+ job = klass.new
221
+ job.jid = msg["jid"]
222
+ job.bid = msg["bid"] if job.respond_to?(:bid)
223
+
224
+ # run the job through server-side middleware
225
+ result = Sidekiq.server_middleware.invoke(job, msg, msg["queue"]) do
226
+ # perform it
227
+ job.perform(*msg["args"])
228
+ true
229
+ end
230
+ return nil unless result
231
+ # jobs do not return a result. they should store any
232
+ # modified state.
233
+ true
192
234
  end
235
+ alias_method :perform_sync, :perform_inline
193
236
 
194
237
  def perform_bulk(args, batch_size: 1_000)
195
- args.each_slice(batch_size).flat_map do |slice|
196
- Sidekiq::Client.push_bulk(@opts.merge("class" => @klass, "args" => slice))
238
+ hash = @opts.transform_keys(&:to_s)
239
+ pool = Thread.current[:sidekiq_via_pool] || @klass.get_sidekiq_options["pool"] || Sidekiq.redis_pool
240
+ client = Sidekiq::Client.new(pool)
241
+ result = args.each_slice(batch_size).flat_map do |slice|
242
+ client.push_bulk(hash.merge("class" => @klass, "args" => slice))
197
243
  end
244
+
245
+ result.is_a?(Enumerator::Lazy) ? result.force : result
198
246
  end
199
247
 
200
248
  # +interval+ must be a timestamp, numeric or something that acts
@@ -238,7 +286,12 @@ module Sidekiq
238
286
  end
239
287
 
240
288
  def perform_async(*args)
241
- client_push("class" => self, "args" => args)
289
+ Setter.new(self, {}).perform_async(*args)
290
+ end
291
+
292
+ # Inline execution of job's perform method after passing through Sidekiq.client_middleware and Sidekiq.server_middleware
293
+ def perform_inline(*args)
294
+ Setter.new(self, {}).perform_inline(*args)
242
295
  end
243
296
 
244
297
  ##
@@ -261,10 +314,8 @@ module Sidekiq
261
314
  #
262
315
  # SomeWorker.perform_bulk([[1], [2], [3]])
263
316
  #
264
- def perform_bulk(items, batch_size: 1_000)
265
- items.each_slice(batch_size).flat_map do |slice|
266
- Sidekiq::Client.push_bulk("class" => self, "args" => slice)
267
- end
317
+ def perform_bulk(*args, **kwargs)
318
+ Setter.new(self, {}).perform_bulk(*args, **kwargs)
268
319
  end
269
320
 
270
321
  # +interval+ must be a timestamp, numeric or something that acts
data/lib/sidekiq.rb CHANGED
@@ -26,6 +26,7 @@ module Sidekiq
26
26
  timeout: 25,
27
27
  poll_interval_average: nil,
28
28
  average_scheduled_poll_interval: 5,
29
+ on_complex_arguments: :warn,
29
30
  error_handlers: [],
30
31
  death_handlers: [],
31
32
  lifecycle_events: {
@@ -102,6 +103,7 @@ module Sidekiq
102
103
  # to disconnect and reopen the socket to get back to the primary.
103
104
  # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
104
105
  # 4985 Use the same logic when a blocking command is force-unblocked
106
+ # The same retry logic is also used in client.rb
105
107
  if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
106
108
  conn.disconnect!
107
109
  retryable = false
@@ -252,6 +254,10 @@ module Sidekiq
252
254
  options[:lifecycle_events][event] << block
253
255
  end
254
256
 
257
+ def self.strict_args!(mode = :raise)
258
+ options[:on_complex_arguments] = mode
259
+ end
260
+
255
261
  # We are shutting down Sidekiq but what about workers that
256
262
  # are working on some long job? This error is
257
263
  # raised in workers that have not finished within the hard
@@ -1,6 +1,6 @@
1
1
  html, body {
2
- background-color: #333 !important;
3
- color: #ddd;
2
+ background-color: #171717 !important;
3
+ color: #DEDEDE;
4
4
  }
5
5
 
6
6
  a,
@@ -30,15 +30,15 @@ span.current-interval,
30
30
 
31
31
  .navbar-inverse {
32
32
  background-color: #222;
33
- border-color: #555;
33
+ border-color: #444;
34
34
  }
35
35
 
36
36
  table {
37
- background-color: #282828;
37
+ background-color: #1D1D1D;
38
38
  }
39
39
 
40
40
  .table-striped > tbody > tr:nth-of-type(odd) {
41
- background-color: #333;
41
+ background-color: #2E2E2E;
42
42
  }
43
43
 
44
44
  .table-bordered,
@@ -48,7 +48,7 @@ table {
48
48
  .table-bordered > tfoot > tr > th,
49
49
  .table-bordered > thead > tr > td,
50
50
  .table-bordered > thead > tr > th {
51
- border: 1px solid #555;
51
+ border: 1px solid #444;
52
52
  }
53
53
 
54
54
  .table-hover > tbody > tr:hover {
@@ -72,9 +72,7 @@ table {
72
72
  background-color: #31708f;
73
73
  }
74
74
 
75
- a:link,
76
- a:active,
77
- a:hover {
75
+ a:link, a:active, a:hover, a:visited {
78
76
  color: #ddd;
79
77
  }
80
78
 
@@ -85,15 +83,13 @@ input {
85
83
  }
86
84
 
87
85
  .summary_bar .summary {
88
- background-color: #222;
89
- border: 1px solid #555;
90
-
91
- box-shadow: 0 0 5px rgba(255, 255, 255, .5);
86
+ background-color: #232323;
87
+ border: 1px solid #444;
92
88
  }
93
89
 
94
90
  .navbar-default {
95
- background-color: #222;
96
- border-color: #555;
91
+ background-color: #0F0F0F;
92
+ border-color: #444;
97
93
  }
98
94
 
99
95
  .navbar-default .navbar-nav > .active > a,
@@ -112,7 +108,7 @@ input {
112
108
  .pagination > li > span {
113
109
  color: #ddd;
114
110
  background-color: #333;
115
- border-color: #555;
111
+ border-color: #444;
116
112
  }
117
113
  .pagination > .disabled > a,
118
114
  .pagination > .disabled > a:focus,
@@ -122,7 +118,7 @@ input {
122
118
  .pagination > .disabled > span:hover {
123
119
  color: #ddd;
124
120
  background-color: #333;
125
- border-color: #555;
121
+ border-color: #444;
126
122
  }
127
123
 
128
124
  .stat {
@@ -21,7 +21,7 @@ body {
21
21
  a {
22
22
  color: #b1003e;
23
23
  }
24
- a:active, a:hover {
24
+ a:active, a:hover, a:focus {
25
25
  color: #4b001a;
26
26
  }
27
27
 
@@ -89,11 +89,10 @@ header.row .pagination {
89
89
  .summary_bar .summary {
90
90
  margin-top: 12px;
91
91
  background-color: #fff;
92
- box-shadow: 0 0 5px rgba(50, 50, 50, 0.25);
93
92
  border-radius: 4px;
93
+ border: 1px solid rgba(0, 0, 0, 0.1);
94
94
  padding: 8px;
95
95
  margin-bottom: 10px;
96
- border-width: 0;
97
96
  }
98
97
  .poll-wrapper {
99
98
  margin: 9px;
@@ -203,6 +202,8 @@ table .table-checkbox label {
203
202
 
204
203
  .navbar .navbar-brand .status {
205
204
  color: #585454;
205
+ display: inline-block;
206
+ width: 75px;
206
207
  }
207
208
 
208
209
 
@@ -350,6 +351,7 @@ img.smallogo {
350
351
  text-align: center;
351
352
  margin-right: 20px;
352
353
  border: 1px solid rgba(0, 0, 0, 0.1);
354
+ border-radius: 4px;
353
355
  padding: 5px;
354
356
  width: 150px;
355
357
  margin-bottom: 20px;
@@ -405,8 +407,6 @@ span.current-interval {
405
407
 
406
408
  div.interval-slider input {
407
409
  width: 160px;
408
- height: 3px;
409
- margin-top: 5px;
410
410
  border-radius: 2px;
411
411
  background: currentcolor;
412
412
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.1
4
+ version: 6.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-07 00:00:00.000000000 Z
11
+ date: 2022-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -67,10 +67,10 @@ files:
67
67
  - bin/sidekiq
68
68
  - bin/sidekiqload
69
69
  - bin/sidekiqmon
70
- - lib/generators/sidekiq/templates/worker.rb.erb
71
- - lib/generators/sidekiq/templates/worker_spec.rb.erb
72
- - lib/generators/sidekiq/templates/worker_test.rb.erb
73
- - lib/generators/sidekiq/worker_generator.rb
70
+ - lib/generators/sidekiq/job_generator.rb
71
+ - lib/generators/sidekiq/templates/job.rb.erb
72
+ - lib/generators/sidekiq/templates/job_spec.rb.erb
73
+ - lib/generators/sidekiq/templates/job_test.rb.erb
74
74
  - lib/sidekiq.rb
75
75
  - lib/sidekiq/api.rb
76
76
  - lib/sidekiq/cli.rb
@@ -85,6 +85,7 @@ files:
85
85
  - lib/sidekiq/job.rb
86
86
  - lib/sidekiq/job_logger.rb
87
87
  - lib/sidekiq/job_retry.rb
88
+ - lib/sidekiq/job_util.rb
88
89
  - lib/sidekiq/launcher.rb
89
90
  - lib/sidekiq/logger.rb
90
91
  - lib/sidekiq/manager.rb
@@ -192,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  - !ruby/object:Gem::Version
193
194
  version: '0'
194
195
  requirements: []
195
- rubygems_version: 3.1.4
196
+ rubygems_version: 3.2.32
196
197
  signing_key:
197
198
  specification_version: 4
198
199
  summary: Simple, efficient background processing for Ruby
@@ -1,57 +0,0 @@
1
- require "rails/generators/named_base"
2
-
3
- module Sidekiq
4
- module Generators # :nodoc:
5
- class WorkerGenerator < ::Rails::Generators::NamedBase # :nodoc:
6
- desc "This generator creates a Sidekiq Worker in app/workers and a corresponding test"
7
-
8
- check_class_collision suffix: "Worker"
9
-
10
- def self.default_generator_root
11
- File.dirname(__FILE__)
12
- end
13
-
14
- def create_worker_file
15
- template "worker.rb.erb", File.join("app/workers", class_path, "#{file_name}_worker.rb")
16
- end
17
-
18
- def create_test_file
19
- return unless test_framework
20
-
21
- if test_framework == :rspec
22
- create_worker_spec
23
- else
24
- create_worker_test
25
- end
26
- end
27
-
28
- private
29
-
30
- def create_worker_spec
31
- template_file = File.join(
32
- "spec/workers",
33
- class_path,
34
- "#{file_name}_worker_spec.rb"
35
- )
36
- template "worker_spec.rb.erb", template_file
37
- end
38
-
39
- def create_worker_test
40
- template_file = File.join(
41
- "test/workers",
42
- class_path,
43
- "#{file_name}_worker_test.rb"
44
- )
45
- template "worker_test.rb.erb", template_file
46
- end
47
-
48
- def file_name
49
- @_file_name ||= super.sub(/_?worker\z/i, "")
50
- end
51
-
52
- def test_framework
53
- ::Rails.application.config.generators.options[:rails][:test_framework]
54
- end
55
- end
56
- end
57
- end