sidekiq 6.4.1 → 6.5.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.
- checksums.yaml +4 -4
- data/Changes.md +47 -1
- data/README.md +1 -1
- data/bin/sidekiqload +16 -10
- data/lib/sidekiq/.DS_Store +0 -0
- data/lib/sidekiq/api.rb +73 -46
- data/lib/sidekiq/cli.rb +38 -37
- data/lib/sidekiq/client.rb +25 -26
- data/lib/sidekiq/component.rb +64 -0
- data/lib/sidekiq/delay.rb +1 -1
- data/lib/sidekiq/extensions/generic_proxy.rb +1 -1
- data/lib/sidekiq/fetch.rb +16 -14
- data/lib/sidekiq/job_retry.rb +29 -28
- data/lib/sidekiq/job_util.rb +15 -9
- data/lib/sidekiq/launcher.rb +31 -29
- data/lib/sidekiq/logger.rb +5 -19
- data/lib/sidekiq/manager.rb +28 -25
- data/lib/sidekiq/middleware/chain.rb +22 -13
- data/lib/sidekiq/middleware/current_attributes.rb +4 -0
- data/lib/sidekiq/middleware/i18n.rb +6 -4
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +1 -1
- data/lib/sidekiq/paginator.rb +2 -2
- data/lib/sidekiq/processor.rb +38 -38
- data/lib/sidekiq/rails.rb +15 -8
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +81 -48
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +11 -10
- data/lib/sidekiq/testing/inline.rb +4 -4
- data/lib/sidekiq/testing.rb +37 -36
- data/lib/sidekiq/transaction_aware_client.rb +45 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/csrf_protection.rb +2 -2
- data/lib/sidekiq/web/helpers.rb +4 -4
- data/lib/sidekiq/worker.rb +18 -13
- data/lib/sidekiq.rb +97 -30
- data/web/assets/javascripts/application.js +58 -26
- data/web/assets/stylesheets/application.css +1 -2
- data/web/locales/pt-br.yml +27 -9
- data/web/views/_summary.erb +1 -1
- data/web/views/busy.erb +3 -3
- metadata +8 -4
- data/lib/sidekiq/exception_handler.rb +0 -27
- data/lib/sidekiq/util.rb +0 -108
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1afbc6a1a0b14403e9148e746c08e0a2b24e634fca05288982c96719675607de
|
4
|
+
data.tar.gz: 3ff3f8df76b565f42030462eb8d09b673b89751dcd6a0b7c41a255789960d321
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8a68611735322d98cc517f1d03ef02394497f8eb505e0db496909cac1f6b7f0179f38ce1966546f717115395102c78fdad9ae0fd947360307b9288dcc22b369
|
7
|
+
data.tar.gz: 163e41dfb153a4e2ec50d407bde08cb8a395909807053f24478a73af1a6a9858b5aec92cbf618d4d066560a2b7bedaa2f88b48f823609e2d78f21320270cb97e
|
data/Changes.md
CHANGED
@@ -2,7 +2,46 @@
|
|
2
2
|
|
3
3
|
[Sidekiq Changes](https://github.com/mperham/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/main/Ent-Changes.md)
|
4
4
|
|
5
|
-
|
5
|
+
6.5.1
|
6
|
+
----------
|
7
|
+
|
8
|
+
- Fix `push_bulk` breakage [#5387]
|
9
|
+
|
10
|
+
6.5.0
|
11
|
+
---------
|
12
|
+
|
13
|
+
- Substantial refactoring of Sidekiq server internals, part of a larger effort
|
14
|
+
to reduce Sidekiq's internal usage of global methods and data, see [docs/global_to_local.md](docs/global_to_local.md) and [docs/middleware.md](docs/middleware.md).
|
15
|
+
- **Add beta support for the `redis-client` gem**. This will become the default Redis driver in Sidekiq 7.0. [#5298]
|
16
|
+
Read more: https://github.com/mperham/sidekiq/wiki/Using-redis-client
|
17
|
+
- **Add beta support for DB transaction-aware client** [#5291]
|
18
|
+
Add this line to your initializer and any jobs created during a transaction
|
19
|
+
will only be pushed to Redis **after the transaction commits**. You will need to add the
|
20
|
+
`after_commit_everywhere` gem to your Gemfile.
|
21
|
+
```ruby
|
22
|
+
Sidekiq.transactional_push!
|
23
|
+
```
|
24
|
+
This feature does not have a lot of production usage yet; please try it out and let us
|
25
|
+
know if you have any issues. It will be fully supported in Sidekiq 7.0 or removed if it
|
26
|
+
proves problematic.
|
27
|
+
- Fix regression with middleware arguments [#5312]
|
28
|
+
|
29
|
+
6.4.2
|
30
|
+
---------
|
31
|
+
|
32
|
+
- Strict argument checking now runs after client-side middleware [#5246]
|
33
|
+
- Fix page events with live polling [#5184]
|
34
|
+
- Many under-the-hood changes to remove all usage of the term "worker"
|
35
|
+
from the Sidekiq codebase and APIs. This mostly involved RDoc and local
|
36
|
+
variable names but a few constants and public APIs were changed. The old
|
37
|
+
APIs will be removed in Sidekiq 7.0.
|
38
|
+
```
|
39
|
+
Sidekiq::DEFAULT_WORKER_OPTIONS -> Sidekiq.default_job_options
|
40
|
+
Sidekiq.default_worker_options -> Sidekiq.default_job_options
|
41
|
+
Sidekiq::Queues["default"].jobs_by_worker(HardJob) -> Sidekiq::Queues["default"].jobs_by_class(HardJob)
|
42
|
+
```
|
43
|
+
|
44
|
+
6.4.1
|
6
45
|
---------
|
7
46
|
|
8
47
|
- Fix pipeline/multi deprecations in redis-rb 4.6
|
@@ -319,6 +358,13 @@ See the [Logging wiki page](https://github.com/mperham/sidekiq/wiki/Logging) for
|
|
319
358
|
- Integrate the StandardRB code formatter to ensure consistent code
|
320
359
|
styling. [#4114, gearnode]
|
321
360
|
|
361
|
+
5.2.10
|
362
|
+
---------
|
363
|
+
|
364
|
+
- Backport fix for CVE-2022-23837.
|
365
|
+
- Migrate to `exists?` for redis-rb.
|
366
|
+
- Lock redis-rb to <4.6 to avoid deprecations.
|
367
|
+
|
322
368
|
5.2.9
|
323
369
|
---------
|
324
370
|
|
data/README.md
CHANGED
data/bin/sidekiqload
CHANGED
@@ -11,6 +11,10 @@ Bundler.require(:default, :load_test)
|
|
11
11
|
require_relative "../lib/sidekiq/cli"
|
12
12
|
require_relative "../lib/sidekiq/launcher"
|
13
13
|
|
14
|
+
if ENV["SIDEKIQ_REDIS_CLIENT"]
|
15
|
+
Sidekiq::RedisConnection.adapter = :redis_client
|
16
|
+
end
|
17
|
+
|
14
18
|
Sidekiq.configure_server do |config|
|
15
19
|
config.options[:concurrency] = 10
|
16
20
|
config.redis = {db: 13, port: 6380}
|
@@ -36,7 +40,6 @@ end
|
|
36
40
|
|
37
41
|
# brew tap shopify/shopify
|
38
42
|
# brew install toxiproxy
|
39
|
-
# gem install toxiproxy
|
40
43
|
# run `toxiproxy-server` in a separate terminal window.
|
41
44
|
require "toxiproxy"
|
42
45
|
# simulate a non-localhost network for realer-world conditions.
|
@@ -90,12 +93,7 @@ iter = 50
|
|
90
93
|
count = 10_000
|
91
94
|
|
92
95
|
iter.times do
|
93
|
-
arr = Array.new(count)
|
94
|
-
[]
|
95
|
-
end
|
96
|
-
count.times do |idx|
|
97
|
-
arr[idx][0] = idx
|
98
|
-
end
|
96
|
+
arr = Array.new(count) { |idx| [idx] }
|
99
97
|
Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
|
100
98
|
end
|
101
99
|
Sidekiq.logger.error "Created #{count * iter} jobs"
|
@@ -124,15 +122,23 @@ Monitoring = Thread.new do
|
|
124
122
|
end
|
125
123
|
end
|
126
124
|
|
125
|
+
def with_latency(latency, &block)
|
126
|
+
Sidekiq.logger.error "Simulating #{latency}ms of latency between Sidekiq and redis"
|
127
|
+
if latency > 0
|
128
|
+
Toxiproxy[:redis].downstream(:latency, latency: latency).apply(&block)
|
129
|
+
else
|
130
|
+
yield
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
127
134
|
begin
|
128
135
|
# RubyProf::exclude_threads = [ Monitoring ]
|
129
136
|
# RubyProf.start
|
130
137
|
events = Sidekiq.options[:lifecycle_events][:startup]
|
131
138
|
events.each(&:call)
|
132
139
|
events.clear
|
133
|
-
|
134
|
-
|
135
|
-
Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
|
140
|
+
|
141
|
+
with_latency(Integer(ENV.fetch("LATENCY", "1"))) do
|
136
142
|
launcher = Sidekiq::Launcher.new(Sidekiq.options)
|
137
143
|
launcher.run
|
138
144
|
|
Binary file
|
data/lib/sidekiq/api.rb
CHANGED
@@ -191,7 +191,7 @@ module Sidekiq
|
|
191
191
|
stat_hash[dates[idx]] = value ? value.to_i : 0
|
192
192
|
end
|
193
193
|
end
|
194
|
-
rescue
|
194
|
+
rescue RedisConnection.adapter::CommandError
|
195
195
|
# mget will trigger a CROSSSLOT error when run against a Cluster
|
196
196
|
# TODO Someone want to add Cluster support?
|
197
197
|
end
|
@@ -217,24 +217,30 @@ module Sidekiq
|
|
217
217
|
include Enumerable
|
218
218
|
|
219
219
|
##
|
220
|
-
#
|
220
|
+
# Fetch all known queues within Redis.
|
221
221
|
#
|
222
|
+
# @return [Array<Sidekiq::Queue>]
|
222
223
|
def self.all
|
223
224
|
Sidekiq.redis { |c| c.sscan_each("queues").to_a }.sort.map { |q| Sidekiq::Queue.new(q) }
|
224
225
|
end
|
225
226
|
|
226
227
|
attr_reader :name
|
227
228
|
|
229
|
+
# @param name [String] the name of the queue
|
228
230
|
def initialize(name = "default")
|
229
231
|
@name = name.to_s
|
230
232
|
@rname = "queue:#{name}"
|
231
233
|
end
|
232
234
|
|
235
|
+
# The current size of the queue within Redis.
|
236
|
+
# This value is real-time and can change between calls.
|
237
|
+
#
|
238
|
+
# @return [Integer] the size
|
233
239
|
def size
|
234
240
|
Sidekiq.redis { |con| con.llen(@rname) }
|
235
241
|
end
|
236
242
|
|
237
|
-
#
|
243
|
+
# @return [Boolean] if the queue is currently paused
|
238
244
|
def paused?
|
239
245
|
false
|
240
246
|
end
|
@@ -243,7 +249,7 @@ module Sidekiq
|
|
243
249
|
# Calculates this queue's latency, the difference in seconds since the oldest
|
244
250
|
# job in the queue was enqueued.
|
245
251
|
#
|
246
|
-
# @return Float
|
252
|
+
# @return [Float] in seconds
|
247
253
|
def latency
|
248
254
|
entry = Sidekiq.redis { |conn|
|
249
255
|
conn.lrange(@rname, -1, -1)
|
@@ -279,12 +285,17 @@ module Sidekiq
|
|
279
285
|
##
|
280
286
|
# Find the job with the given JID within this queue.
|
281
287
|
#
|
282
|
-
# This is a slow, inefficient operation. Do not use under
|
288
|
+
# This is a *slow, inefficient* operation. Do not use under
|
283
289
|
# normal conditions.
|
290
|
+
#
|
291
|
+
# @param jid [String] the job_id to look for
|
292
|
+
# @return [Sidekiq::JobRecord]
|
293
|
+
# @return [nil] if not found
|
284
294
|
def find_job(jid)
|
285
295
|
detect { |j| j.jid == jid }
|
286
296
|
end
|
287
297
|
|
298
|
+
# delete all jobs within this queue
|
288
299
|
def clear
|
289
300
|
Sidekiq.redis do |conn|
|
290
301
|
conn.multi do |transaction|
|
@@ -294,6 +305,10 @@ module Sidekiq
|
|
294
305
|
end
|
295
306
|
end
|
296
307
|
alias_method :💣, :clear
|
308
|
+
|
309
|
+
def as_json(options = nil) # :nodoc:
|
310
|
+
{name: name} # 5336
|
311
|
+
end
|
297
312
|
end
|
298
313
|
|
299
314
|
##
|
@@ -306,15 +321,16 @@ module Sidekiq
|
|
306
321
|
class JobRecord
|
307
322
|
attr_reader :item
|
308
323
|
attr_reader :value
|
324
|
+
attr_reader :queue
|
309
325
|
|
310
|
-
def initialize(item, queue_name = nil)
|
326
|
+
def initialize(item, queue_name = nil) # :nodoc:
|
311
327
|
@args = nil
|
312
328
|
@value = item
|
313
329
|
@item = item.is_a?(Hash) ? item : parse(item)
|
314
330
|
@queue = queue_name || @item["queue"]
|
315
331
|
end
|
316
332
|
|
317
|
-
def parse(item)
|
333
|
+
def parse(item) # :nodoc:
|
318
334
|
Sidekiq.load_json(item)
|
319
335
|
rescue JSON::ParserError
|
320
336
|
# If the job payload in Redis is invalid JSON, we'll load
|
@@ -354,31 +370,31 @@ module Sidekiq
|
|
354
370
|
def display_args
|
355
371
|
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
356
372
|
@display_args ||= case klass
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
373
|
+
when /\ASidekiq::Extensions::Delayed/
|
374
|
+
safe_load(args[0], args) do |_, _, arg, kwarg|
|
375
|
+
if !kwarg || kwarg.empty?
|
376
|
+
arg
|
377
|
+
else
|
378
|
+
[arg, kwarg]
|
379
|
+
end
|
380
|
+
end
|
381
|
+
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
382
|
+
job_args = self["wrapped"] ? args[0]["arguments"] : []
|
383
|
+
if (self["wrapped"] || args[0]) == "ActionMailer::DeliveryJob"
|
384
|
+
# remove MailerClass, mailer_method and 'deliver_now'
|
385
|
+
job_args.drop(3)
|
386
|
+
elsif (self["wrapped"] || args[0]) == "ActionMailer::MailDeliveryJob"
|
387
|
+
# remove MailerClass, mailer_method and 'deliver_now'
|
388
|
+
job_args.drop(3).first["args"]
|
389
|
+
else
|
390
|
+
job_args
|
391
|
+
end
|
392
|
+
else
|
393
|
+
if self["encrypt"]
|
394
|
+
# no point in showing 150+ bytes of random garbage
|
395
|
+
args[-1] = "[encrypted data]"
|
396
|
+
end
|
397
|
+
args
|
382
398
|
end
|
383
399
|
end
|
384
400
|
|
@@ -412,15 +428,12 @@ module Sidekiq
|
|
412
428
|
end
|
413
429
|
end
|
414
430
|
|
415
|
-
attr_reader :queue
|
416
|
-
|
417
431
|
def latency
|
418
432
|
now = Time.now.to_f
|
419
433
|
now - (@item["enqueued_at"] || @item["created_at"] || now)
|
420
434
|
end
|
421
435
|
|
422
|
-
|
423
|
-
# Remove this job from the queue.
|
436
|
+
# Remove this job from the queue
|
424
437
|
def delete
|
425
438
|
count = Sidekiq.redis { |conn|
|
426
439
|
conn.lrem("queue:#{@queue}", 1, @value)
|
@@ -428,6 +441,7 @@ module Sidekiq
|
|
428
441
|
count != 0
|
429
442
|
end
|
430
443
|
|
444
|
+
# Access arbitrary attributes within the job hash
|
431
445
|
def [](name)
|
432
446
|
# nil will happen if the JSON fails to parse.
|
433
447
|
# We don't guarantee Sidekiq will work with bad job JSON but we should
|
@@ -442,7 +456,8 @@ module Sidekiq
|
|
442
456
|
rescue => ex
|
443
457
|
# #1761 in dev mode, it's possible to have jobs enqueued which haven't been loaded into
|
444
458
|
# memory yet so the YAML can't be loaded.
|
445
|
-
|
459
|
+
# TODO is this still necessary? Zeitwerk reloader should handle?
|
460
|
+
Sidekiq.logger.warn "Unable to load YAML: #{ex.message}" unless Sidekiq.config[:environment] == "development"
|
446
461
|
default
|
447
462
|
end
|
448
463
|
|
@@ -464,13 +479,15 @@ module Sidekiq
|
|
464
479
|
end
|
465
480
|
end
|
466
481
|
|
482
|
+
# Represents a job within a Redis sorted set where the score
|
483
|
+
# represents a timestamp for the job.
|
467
484
|
class SortedEntry < JobRecord
|
468
485
|
attr_reader :score
|
469
486
|
attr_reader :parent
|
470
487
|
|
471
|
-
def initialize(parent, score, item)
|
488
|
+
def initialize(parent, score, item) # :nodoc:
|
472
489
|
super(item)
|
473
|
-
@score = score
|
490
|
+
@score = Float(score)
|
474
491
|
@parent = parent
|
475
492
|
end
|
476
493
|
|
@@ -486,12 +503,17 @@ module Sidekiq
|
|
486
503
|
end
|
487
504
|
end
|
488
505
|
|
506
|
+
# Change the scheduled time for this job.
|
507
|
+
#
|
508
|
+
# @param [Time] the new timestamp when this job will be enqueued.
|
489
509
|
def reschedule(at)
|
490
510
|
Sidekiq.redis do |conn|
|
491
511
|
conn.zincrby(@parent.name, at.to_f - @score, Sidekiq.dump_json(@item))
|
492
512
|
end
|
493
513
|
end
|
494
514
|
|
515
|
+
# Enqueue this job from the scheduled or dead set so it will
|
516
|
+
# be executed at some point in the near future.
|
495
517
|
def add_to_queue
|
496
518
|
remove_job do |message|
|
497
519
|
msg = Sidekiq.load_json(message)
|
@@ -499,6 +521,8 @@ module Sidekiq
|
|
499
521
|
end
|
500
522
|
end
|
501
523
|
|
524
|
+
# enqueue this job from the retry set so it will be executed
|
525
|
+
# at some point in the near future.
|
502
526
|
def retry
|
503
527
|
remove_job do |message|
|
504
528
|
msg = Sidekiq.load_json(message)
|
@@ -507,8 +531,7 @@ module Sidekiq
|
|
507
531
|
end
|
508
532
|
end
|
509
533
|
|
510
|
-
|
511
|
-
# Place job in the dead set
|
534
|
+
# Move this job from its current set into the Dead set.
|
512
535
|
def kill
|
513
536
|
remove_job do |message|
|
514
537
|
DeadSet.new.kill(message)
|
@@ -587,6 +610,10 @@ module Sidekiq
|
|
587
610
|
end
|
588
611
|
end
|
589
612
|
alias_method :💣, :clear
|
613
|
+
|
614
|
+
def as_json(options = nil) # :nodoc:
|
615
|
+
{name: name} # 5336
|
616
|
+
end
|
590
617
|
end
|
591
618
|
|
592
619
|
class JobSet < SortedSet
|
@@ -606,7 +633,7 @@ module Sidekiq
|
|
606
633
|
range_start = page * page_size + offset_size
|
607
634
|
range_end = range_start + page_size - 1
|
608
635
|
elements = Sidekiq.redis { |conn|
|
609
|
-
conn.zrange name, range_start, range_end,
|
636
|
+
conn.zrange name, range_start, range_end, withscores: true
|
610
637
|
}
|
611
638
|
break if elements.empty?
|
612
639
|
page -= 1
|
@@ -629,7 +656,7 @@ module Sidekiq
|
|
629
656
|
end
|
630
657
|
|
631
658
|
elements = Sidekiq.redis { |conn|
|
632
|
-
conn.zrangebyscore(name, begin_score, end_score,
|
659
|
+
conn.zrangebyscore(name, begin_score, end_score, withscores: true)
|
633
660
|
}
|
634
661
|
|
635
662
|
elements.each_with_object([]) do |element, result|
|
@@ -758,11 +785,11 @@ module Sidekiq
|
|
758
785
|
end
|
759
786
|
|
760
787
|
def self.max_jobs
|
761
|
-
Sidekiq
|
788
|
+
Sidekiq[:dead_max_jobs]
|
762
789
|
end
|
763
790
|
|
764
791
|
def self.timeout
|
765
|
-
Sidekiq
|
792
|
+
Sidekiq[:dead_timeout_in_seconds]
|
766
793
|
end
|
767
794
|
end
|
768
795
|
|
@@ -964,7 +991,7 @@ module Sidekiq
|
|
964
991
|
procs.sort.each do |key|
|
965
992
|
valid, workers = conn.pipelined { |pipeline|
|
966
993
|
pipeline.exists?(key)
|
967
|
-
pipeline.hgetall("#{key}:
|
994
|
+
pipeline.hgetall("#{key}:work")
|
968
995
|
}
|
969
996
|
next unless valid
|
970
997
|
workers.each_pair do |tid, json|
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -9,18 +9,23 @@ require "erb"
|
|
9
9
|
require "fileutils"
|
10
10
|
|
11
11
|
require "sidekiq"
|
12
|
+
require "sidekiq/component"
|
12
13
|
require "sidekiq/launcher"
|
13
|
-
require "sidekiq/util"
|
14
14
|
|
15
|
-
module Sidekiq
|
15
|
+
module Sidekiq # :nodoc:
|
16
16
|
class CLI
|
17
|
-
include
|
17
|
+
include Sidekiq::Component
|
18
18
|
include Singleton unless $TESTING
|
19
19
|
|
20
20
|
attr_accessor :launcher
|
21
21
|
attr_accessor :environment
|
22
|
+
attr_accessor :config
|
23
|
+
|
24
|
+
def parse(args = ARGV.dup)
|
25
|
+
@config = Sidekiq
|
26
|
+
@config[:error_handlers].clear
|
27
|
+
@config[:error_handlers] << @config.method(:default_error_handler)
|
22
28
|
|
23
|
-
def parse(args = ARGV)
|
24
29
|
setup_options(args)
|
25
30
|
initialize_logger
|
26
31
|
validate!
|
@@ -36,7 +41,7 @@ module Sidekiq
|
|
36
41
|
def run(boot_app: true)
|
37
42
|
boot_application if boot_app
|
38
43
|
|
39
|
-
if environment == "development" && $stdout.tty? &&
|
44
|
+
if environment == "development" && $stdout.tty? && @config.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
|
40
45
|
print_banner
|
41
46
|
end
|
42
47
|
logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
|
@@ -67,7 +72,7 @@ module Sidekiq
|
|
67
72
|
|
68
73
|
# touch the connection pool so it is created before we
|
69
74
|
# fire startup and start multithreading.
|
70
|
-
info =
|
75
|
+
info = @config.redis_info
|
71
76
|
ver = info["redis_version"]
|
72
77
|
raise "You are connecting to Redis v#{ver}, Sidekiq requires Redis v4.0.0 or greater" if ver < "4"
|
73
78
|
|
@@ -85,22 +90,22 @@ module Sidekiq
|
|
85
90
|
|
86
91
|
# Since the user can pass us a connection pool explicitly in the initializer, we
|
87
92
|
# need to verify the size is large enough or else Sidekiq's performance is dramatically slowed.
|
88
|
-
cursize =
|
89
|
-
needed =
|
93
|
+
cursize = @config.redis_pool.size
|
94
|
+
needed = @config[:concurrency] + 2
|
90
95
|
raise "Your pool of #{cursize} Redis connections is too small, please increase the size to at least #{needed}" if cursize < needed
|
91
96
|
|
92
97
|
# cache process identity
|
93
|
-
|
98
|
+
@config[:identity] = identity
|
94
99
|
|
95
100
|
# Touch middleware so it isn't lazy loaded by multiple threads, #3043
|
96
|
-
|
101
|
+
@config.server_middleware
|
97
102
|
|
98
103
|
# Before this point, the process is initializing with just the main thread.
|
99
104
|
# Starting here the process will now have multiple threads running.
|
100
105
|
fire_event(:startup, reverse: false, reraise: true)
|
101
106
|
|
102
|
-
logger.debug { "Client Middleware: #{
|
103
|
-
logger.debug { "Server Middleware: #{
|
107
|
+
logger.debug { "Client Middleware: #{@config.client_middleware.map(&:klass).join(", ")}" }
|
108
|
+
logger.debug { "Server Middleware: #{@config.server_middleware.map(&:klass).join(", ")}" }
|
104
109
|
|
105
110
|
launch(self_read)
|
106
111
|
end
|
@@ -110,13 +115,13 @@ module Sidekiq
|
|
110
115
|
logger.info "Starting processing, hit Ctrl-C to stop"
|
111
116
|
end
|
112
117
|
|
113
|
-
@launcher = Sidekiq::Launcher.new(
|
118
|
+
@launcher = Sidekiq::Launcher.new(@config)
|
114
119
|
|
115
120
|
begin
|
116
121
|
launcher.run
|
117
122
|
|
118
|
-
while
|
119
|
-
signal =
|
123
|
+
while self_read.wait_readable
|
124
|
+
signal = self_read.gets.strip
|
120
125
|
handle_signal(signal)
|
121
126
|
end
|
122
127
|
rescue Interrupt
|
@@ -173,25 +178,25 @@ module Sidekiq
|
|
173
178
|
# Heroku sends TERM and then waits 30 seconds for process to exit.
|
174
179
|
"TERM" => ->(cli) { raise Interrupt },
|
175
180
|
"TSTP" => ->(cli) {
|
176
|
-
|
181
|
+
cli.logger.info "Received TSTP, no longer accepting new work"
|
177
182
|
cli.launcher.quiet
|
178
183
|
},
|
179
184
|
"TTIN" => ->(cli) {
|
180
185
|
Thread.list.each do |thread|
|
181
|
-
|
186
|
+
cli.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
|
182
187
|
if thread.backtrace
|
183
|
-
|
188
|
+
cli.logger.warn thread.backtrace.join("\n")
|
184
189
|
else
|
185
|
-
|
190
|
+
cli.logger.warn "<no backtrace available>"
|
186
191
|
end
|
187
192
|
end
|
188
193
|
}
|
189
194
|
}
|
190
|
-
UNHANDLED_SIGNAL_HANDLER = ->(cli) {
|
195
|
+
UNHANDLED_SIGNAL_HANDLER = ->(cli) { cli.logger.info "No signal handler registered, ignoring" }
|
191
196
|
SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
|
192
197
|
|
193
198
|
def handle_signal(sig)
|
194
|
-
|
199
|
+
logger.debug "Got #{sig} signal"
|
195
200
|
SIGNAL_HANDLERS[sig].call(self)
|
196
201
|
end
|
197
202
|
|
@@ -237,7 +242,7 @@ module Sidekiq
|
|
237
242
|
config_dir = if File.directory?(opts[:require].to_s)
|
238
243
|
File.join(opts[:require], "config")
|
239
244
|
else
|
240
|
-
File.join(
|
245
|
+
File.join(@config[:require], "config")
|
241
246
|
end
|
242
247
|
|
243
248
|
%w[sidekiq.yml sidekiq.yml.erb].each do |config_file|
|
@@ -254,27 +259,23 @@ module Sidekiq
|
|
254
259
|
opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if opts[:concurrency].nil? && ENV["RAILS_MAX_THREADS"]
|
255
260
|
|
256
261
|
# merge with defaults
|
257
|
-
|
258
|
-
end
|
259
|
-
|
260
|
-
def options
|
261
|
-
Sidekiq.options
|
262
|
+
@config.merge!(opts)
|
262
263
|
end
|
263
264
|
|
264
265
|
def boot_application
|
265
266
|
ENV["RACK_ENV"] = ENV["RAILS_ENV"] = environment
|
266
267
|
|
267
|
-
if File.directory?(
|
268
|
+
if File.directory?(@config[:require])
|
268
269
|
require "rails"
|
269
270
|
if ::Rails::VERSION::MAJOR < 5
|
270
271
|
raise "Sidekiq no longer supports this version of Rails"
|
271
272
|
else
|
272
273
|
require "sidekiq/rails"
|
273
|
-
require File.expand_path("#{
|
274
|
+
require File.expand_path("#{@config[:require]}/config/environment.rb")
|
274
275
|
end
|
275
|
-
|
276
|
+
@config[:tag] ||= default_tag
|
276
277
|
else
|
277
|
-
require
|
278
|
+
require @config[:require]
|
278
279
|
end
|
279
280
|
end
|
280
281
|
|
@@ -291,18 +292,18 @@ module Sidekiq
|
|
291
292
|
end
|
292
293
|
|
293
294
|
def validate!
|
294
|
-
if !File.exist?(
|
295
|
-
(File.directory?(
|
295
|
+
if !File.exist?(@config[:require]) ||
|
296
|
+
(File.directory?(@config[:require]) && !File.exist?("#{@config[:require]}/config/application.rb"))
|
296
297
|
logger.info "=================================================================="
|
297
298
|
logger.info " Please point Sidekiq to a Rails application or a Ruby file "
|
298
|
-
logger.info " to load your
|
299
|
+
logger.info " to load your job classes with -r [DIR|FILE]."
|
299
300
|
logger.info "=================================================================="
|
300
301
|
logger.info @parser
|
301
302
|
die(1)
|
302
303
|
end
|
303
304
|
|
304
305
|
[:concurrency, :timeout].each do |opt|
|
305
|
-
raise ArgumentError, "#{opt}: #{
|
306
|
+
raise ArgumentError, "#{opt}: #{@config[opt]} is not a valid value" if @config[opt].to_i <= 0
|
306
307
|
end
|
307
308
|
end
|
308
309
|
|
@@ -336,7 +337,7 @@ module Sidekiq
|
|
336
337
|
parse_queue opts, queue, weight
|
337
338
|
end
|
338
339
|
|
339
|
-
o.on "-r", "--require [PATH|DIR]", "Location of Rails application with
|
340
|
+
o.on "-r", "--require [PATH|DIR]", "Location of Rails application with jobs or file to require" do |arg|
|
340
341
|
opts[:require] = arg
|
341
342
|
end
|
342
343
|
|
@@ -376,7 +377,7 @@ module Sidekiq
|
|
376
377
|
end
|
377
378
|
|
378
379
|
def initialize_logger
|
379
|
-
|
380
|
+
@config.logger.level = ::Logger::DEBUG if @config[:verbose]
|
380
381
|
end
|
381
382
|
|
382
383
|
def parse_config(path)
|