sidekiq 7.3.8 → 8.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +64 -0
  3. data/README.md +16 -13
  4. data/bin/sidekiqload +10 -10
  5. data/bin/webload +69 -0
  6. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +90 -67
  7. data/lib/sidekiq/api.rb +122 -38
  8. data/lib/sidekiq/capsule.rb +6 -6
  9. data/lib/sidekiq/cli.rb +15 -19
  10. data/lib/sidekiq/client.rb +13 -16
  11. data/lib/sidekiq/component.rb +40 -2
  12. data/lib/sidekiq/config.rb +20 -16
  13. data/lib/sidekiq/embedded.rb +2 -1
  14. data/lib/sidekiq/iterable_job.rb +1 -0
  15. data/lib/sidekiq/job/iterable.rb +14 -5
  16. data/lib/sidekiq/job_logger.rb +4 -4
  17. data/lib/sidekiq/job_retry.rb +17 -5
  18. data/lib/sidekiq/job_util.rb +5 -1
  19. data/lib/sidekiq/launcher.rb +2 -1
  20. data/lib/sidekiq/logger.rb +19 -70
  21. data/lib/sidekiq/manager.rb +0 -1
  22. data/lib/sidekiq/metrics/query.rb +71 -45
  23. data/lib/sidekiq/metrics/shared.rb +8 -5
  24. data/lib/sidekiq/metrics/tracking.rb +9 -7
  25. data/lib/sidekiq/middleware/current_attributes.rb +5 -17
  26. data/lib/sidekiq/paginator.rb +8 -1
  27. data/lib/sidekiq/processor.rb +21 -14
  28. data/lib/sidekiq/profiler.rb +72 -0
  29. data/lib/sidekiq/rails.rb +43 -55
  30. data/lib/sidekiq/redis_client_adapter.rb +0 -1
  31. data/lib/sidekiq/redis_connection.rb +14 -3
  32. data/lib/sidekiq/testing.rb +2 -2
  33. data/lib/sidekiq/version.rb +2 -2
  34. data/lib/sidekiq/web/action.rb +122 -83
  35. data/lib/sidekiq/web/application.rb +345 -332
  36. data/lib/sidekiq/web/config.rb +117 -0
  37. data/lib/sidekiq/web/helpers.rb +41 -16
  38. data/lib/sidekiq/web/router.rb +60 -76
  39. data/lib/sidekiq/web.rb +50 -156
  40. data/lib/sidekiq.rb +2 -2
  41. data/sidekiq.gemspec +6 -6
  42. data/web/assets/javascripts/application.js +6 -13
  43. data/web/assets/javascripts/base-charts.js +30 -16
  44. data/web/assets/javascripts/chartjs-adapter-date-fns.min.js +7 -0
  45. data/web/assets/javascripts/dashboard-charts.js +2 -0
  46. data/web/assets/javascripts/dashboard.js +6 -0
  47. data/web/assets/javascripts/metrics.js +16 -34
  48. data/web/assets/stylesheets/style.css +757 -0
  49. data/web/locales/ar.yml +1 -0
  50. data/web/locales/cs.yml +1 -0
  51. data/web/locales/da.yml +1 -0
  52. data/web/locales/de.yml +1 -0
  53. data/web/locales/el.yml +1 -0
  54. data/web/locales/en.yml +9 -0
  55. data/web/locales/es.yml +24 -2
  56. data/web/locales/fa.yml +1 -0
  57. data/web/locales/fr.yml +1 -0
  58. data/web/locales/gd.yml +1 -0
  59. data/web/locales/he.yml +1 -0
  60. data/web/locales/hi.yml +1 -0
  61. data/web/locales/it.yml +8 -0
  62. data/web/locales/ja.yml +1 -0
  63. data/web/locales/ko.yml +1 -0
  64. data/web/locales/lt.yml +1 -0
  65. data/web/locales/nb.yml +1 -0
  66. data/web/locales/nl.yml +1 -0
  67. data/web/locales/pl.yml +1 -0
  68. data/web/locales/{pt-br.yml → pt-BR.yml} +2 -1
  69. data/web/locales/pt.yml +1 -0
  70. data/web/locales/ru.yml +1 -0
  71. data/web/locales/sv.yml +1 -0
  72. data/web/locales/ta.yml +1 -0
  73. data/web/locales/tr.yml +1 -0
  74. data/web/locales/uk.yml +1 -0
  75. data/web/locales/ur.yml +1 -0
  76. data/web/locales/vi.yml +1 -0
  77. data/web/locales/{zh-cn.yml → zh-CN.yml} +85 -73
  78. data/web/locales/{zh-tw.yml → zh-TW.yml} +2 -1
  79. data/web/views/_footer.erb +31 -34
  80. data/web/views/_job_info.erb +91 -89
  81. data/web/views/_metrics_period_select.erb +13 -10
  82. data/web/views/_nav.erb +14 -21
  83. data/web/views/_paging.erb +23 -21
  84. data/web/views/_poll_link.erb +2 -2
  85. data/web/views/_summary.erb +16 -16
  86. data/web/views/busy.erb +124 -122
  87. data/web/views/dashboard.erb +63 -64
  88. data/web/views/dead.erb +31 -27
  89. data/web/views/filtering.erb +3 -3
  90. data/web/views/layout.erb +13 -29
  91. data/web/views/metrics.erb +75 -81
  92. data/web/views/metrics_for_job.erb +45 -46
  93. data/web/views/morgue.erb +61 -70
  94. data/web/views/profiles.erb +43 -0
  95. data/web/views/queue.erb +54 -52
  96. data/web/views/queues.erb +43 -41
  97. data/web/views/retries.erb +66 -75
  98. data/web/views/retry.erb +32 -27
  99. data/web/views/scheduled.erb +58 -54
  100. data/web/views/scheduled_job_info.erb +1 -1
  101. metadata +25 -28
  102. data/web/assets/stylesheets/application-dark.css +0 -147
  103. data/web/assets/stylesheets/application-rtl.css +0 -163
  104. data/web/assets/stylesheets/application.css +0 -759
  105. data/web/assets/stylesheets/bootstrap-rtl.min.css +0 -9
  106. data/web/assets/stylesheets/bootstrap.css +0 -5
  107. data/web/views/_status.erb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec7c9a4bea6982200a069a9a2f7c134811ccbf1aaceb56a8cb708893cab6e301
4
- data.tar.gz: e59152e78eccbf714e485a7772e3a62681974abd114ebd608432c5ab93f55211
3
+ metadata.gz: 5862bbba5b859c1983788b6aeb49193fad724a1186426084c1e42747cb226ba2
4
+ data.tar.gz: 11fbaba14b814b87d09d809173ca59f9477c119f9ab6d556e4a9baa8e4e83d63
5
5
  SHA512:
6
- metadata.gz: 5aac99a9f1a385baaac0204c2799b9821c2146ca045eb2cdabc92ac54da8f20ae6239183eed5256bd96e8c45a8538596aa13714f5dc8fb4943565ec86df16dc9
7
- data.tar.gz: 7ae68faedfc60d2354335709e36b51d9217bead4bfcf2e2d9d60a4b321cfcafdf931680f298bae061ac412e26d898b82dc7c7f15549909834f93251f7745bb13
6
+ metadata.gz: 67d640ff21778c036ba15db434bafe0582a61e1b462d1bee2502fa7a9b8978208b4099c46d8ad6bd6214f198558de8985deeb11b6e7d99f1e603b15f087f0215
7
+ data.tar.gz: 4becc4ea36c062f52667fea91d4f49b5bfb759fe43f75ef6427c1aeacdc36764408f442cafccc3595585cf13ef2ff71da98212d7db0fcb89ff198ace0cd19caa
data/Changes.md CHANGED
@@ -2,6 +2,70 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/sidekiq/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/sidekiq/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/sidekiq/sidekiq/blob/main/Ent-Changes.md)
4
4
 
5
+ HEAD
6
+ ----------
7
+
8
+ - Configure Vernier output directory [#6674]
9
+ - Rework Rails integration [#6669]
10
+ - Implement flash messages for the Web UI [#6675]
11
+
12
+ 8.0.2
13
+ ----------
14
+
15
+ - Add `on(:exit)` event to run code right before the Sidekiq process exits [#6637]
16
+ - Metrics page crashes with Rack 3.1+ [#6646]
17
+
18
+ 8.0.1
19
+ ----------
20
+
21
+ - Relax Redis requirement to 7.0 for compatibility with AWS and Ubuntu 24.04 LTS. [#6630]
22
+
23
+ 8.0.0
24
+ ----------
25
+
26
+ - **WARNING** The underlying class name for Active Jobs has changed from `ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper` to `Sidekiq::ActiveJob::Wrapper`.
27
+ The old name will still work in 8.x.
28
+ - **WARNING** The `created_at`, `enqueued_at`, `failed_at` and `retried_at` attributes are now stored as epoch milliseconds, rather than epoch floats.
29
+ This is meant to avoid precision issues with JSON and JavaScript's 53-bit Floats.
30
+ Example: `"created_at" => 1234567890.123456` -> `"created_at" => 1234567890123`.
31
+ - **NEW FEATURE** Job Profiling is now supported with [Vernier](https://vernier.prof)
32
+ which makes it really easy to performance tune your slow jobs.
33
+ The Web UI contains a new **Profiles** tab to view any collected profile data.
34
+ Please read the new [Profiling](https://github.com/sidekiq/sidekiq/wiki/Profiling) wiki page for details.
35
+ - **NEW FEATURE** Job Metrics now store up to 72 hours of data and the Web UI allows display of 24/48/72 hours. [#6614]
36
+ - CurrentAttribute support now uses `ActiveJob::Arguments` to serialize the context object, supporting Symbols and GlobalID.
37
+ The change should be backwards compatible. [#6510]
38
+ - Freshen up `Sidekiq::Web` to simplify the code and improve security [#6532]
39
+ The CSS has been rewritten from scratch to remove the Bootstrap framework.
40
+ - Add `on_cancel` callback for iterable jobs [#6607]
41
+ - Add `cursor` reader to get the current cursor inside iterable jobs [#6606]
42
+ - Default error logging has been modified to use Ruby's `Exception#detailed_message` and `#full_message` APIs.
43
+ - CI now runs against Redis, Dragonfly and Valkey.
44
+ - Job tags now allow custom CSS display [#6595]
45
+ - The Web UI's language picker now shows options in the native language
46
+ - Remove global variable usage within the codebase
47
+ - Colorize and adjust logging for easier reading
48
+ - Adjust Sidekiq's default thread priority to -1 for a 50ms timeslice.
49
+ This can help avoid TimeoutErrors when Sidekiq is overloaded. [#6543]
50
+ - Use `Logger#with_level`, remove Sidekiq's custom impl
51
+ - Remove `base64` gem dependency
52
+ - Support: (Dragonfly 1.27+, Valkey 7.2+, Redis 7.2+), Ruby 3.2+, Rails 7.0+
53
+
54
+ 7.3.10
55
+ ----------
56
+
57
+ - Deprecate Redis :password as a String to avoid log disclosure. [#6625]
58
+ Use a Proc instead: `config.redis = { password: ->(username) { "password" } }`
59
+
60
+ 7.3.9
61
+ ----------
62
+
63
+ - Only require activejob if necessary [#6584]
64
+ You might get `uninitialized constant Sidekiq::ActiveJob` if you
65
+ `require 'sidekiq'` before `require 'rails'`.
66
+ - Fix iterable job cancellation [#6589]
67
+ - Web UI accessibility improvements [#6604]
68
+
5
69
  7.3.8
6
70
  ----------
7
71
 
data/README.md CHANGED
@@ -4,21 +4,23 @@ Sidekiq
4
4
  [![Gem Version](https://badge.fury.io/rb/sidekiq.svg)](https://rubygems.org/gems/sidekiq)
5
5
  ![Build](https://github.com/sidekiq/sidekiq/workflows/CI/badge.svg)
6
6
 
7
- Simple, efficient background processing for Ruby.
7
+ Simple, efficient background jobs for Ruby.
8
8
 
9
9
  Sidekiq uses threads to handle many jobs at the same time in the
10
- same process. It does not require Rails but will integrate tightly with
11
- Rails to make background processing dead simple.
10
+ same process. Sidekiq can be used by any Ruby application.
12
11
 
13
12
 
14
13
  Requirements
15
14
  -----------------
16
15
 
17
- - Redis: Redis 6.2+ or Dragonfly 1.13+
18
- - Ruby: MRI 2.7+ or JRuby 9.3+.
16
+ - Redis: Redis 7.0+, Valkey 7.2+ or Dragonfly 1.27+
17
+ - Ruby: MRI 3.2+ or JRuby 9.4+.
19
18
 
20
- Sidekiq 7.0 supports Rails 6.0+ but does not require it.
21
- As of 7.2, Sidekiq supports Dragonfly as an alternative to Redis for data storage.
19
+ Sidekiq 8.0 supports Rails and Active Job 7.0+.
20
+
21
+ Sidekiq supports [Valkey](https://valkey.io) and [Dragonfly](https://www.dragonflydb.io) as Redis alternatives.
22
+ Redis 7.2.4 is considered to be the canonical implementation.
23
+ Incompatibilities with that version are considered bugs.
22
24
 
23
25
  Installation
24
26
  -----------------
@@ -42,6 +44,7 @@ The benchmark in `bin/sidekiqload` creates 500,000 no-op jobs and drains them as
42
44
  This requires a lot of Redis network I/O and JSON parsing.
43
45
  This benchmark is IO-bound so we increase the concurrency to 25.
44
46
  If your application is sending lots of emails or performing other network-intensive work, you could see a similar benefit but be careful not to saturate the CPU.
47
+ Real world applications will rarely if ever need to use concurrency greater than 10.
45
48
 
46
49
  Version | Time to process 500k jobs | Throughput (jobs/sec) | Ruby | Concurrency | Job Type
47
50
  -----------------|------|---------|---------|------------------------|---
@@ -62,7 +65,7 @@ Want to Upgrade?
62
65
  Use `bundle up sidekiq` to upgrade Sidekiq and all its dependencies.
63
66
  Upgrade notes between each major version can be found in the `docs/` directory.
64
67
 
65
- I also sell Sidekiq Pro and Sidekiq Enterprise, extensions to Sidekiq which provide more
68
+ I also sell [Sidekiq Pro](https://billing.contribsys.com/spro/) and [Sidekiq Enterprise](https://billing.contribsys.com/sent/new.cgi), extensions to Sidekiq which provide more
66
69
  features, a commercial-friendly license and allow you to support high
67
70
  quality open source development all at the same time. Please see the
68
71
  [Sidekiq](https://sidekiq.org/) homepage for more detail.
@@ -71,7 +74,7 @@ quality open source development all at the same time. Please see the
71
74
  Problems?
72
75
  -----------------
73
76
 
74
- **Please do not directly email any Sidekiq committers with questions or problems.**
77
+ **Do not directly email any Sidekiq committers with questions or problems.**
75
78
  A community is best served when discussions are held in public.
76
79
 
77
80
  If you have a problem, please review the [FAQ](https://github.com/sidekiq/sidekiq/wiki/FAQ) and [Troubleshooting](https://github.com/sidekiq/sidekiq/wiki/Problems-and-Troubleshooting) wiki pages.
@@ -86,21 +89,21 @@ Useful resources:
86
89
  * Occasional announcements are made to the [@sidekiq](https://ruby.social/@sidekiq) Mastodon account.
87
90
  * The [Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow has lots of useful Q & A.
88
91
 
89
- Every Thursday morning is Sidekiq office hour: I video chat and answer questions.
92
+ Every Thursday morning is Sidekiq Office Hour: I video chat and answer questions.
90
93
  See the [Sidekiq support page](https://sidekiq.org/support.html) for details.
91
94
 
92
95
  Contributing
93
96
  -----------------
94
97
 
95
- Please see [the contributing guidelines](https://github.com/sidekiq/sidekiq/blob/main/.github/contributing.md).
98
+ See [the contributing guidelines](https://github.com/sidekiq/sidekiq/blob/main/.github/contributing.md).
96
99
 
97
100
  License
98
101
  -----------------
99
102
 
100
- Please see [LICENSE.txt](https://github.com/sidekiq/sidekiq/blob/main/LICENSE.txt) for licensing details.
103
+ See [LICENSE.txt](https://github.com/sidekiq/sidekiq/blob/main/LICENSE.txt) for licensing details.
101
104
  The license for Sidekiq Pro and Sidekiq Enterprise can be found in [COMM-LICENSE.txt](https://github.com/sidekiq/sidekiq/blob/main/COMM-LICENSE.txt).
102
105
 
103
106
  Author
104
107
  -----------------
105
108
 
106
- Mike Perham, [@getajobmike](https://ruby.social/@getajobmike) / [@sidekiq](https://ruby.social/@sidekiq), [https://www.mikeperham.com](https://www.mikeperham.com) / [https://www.contribsys.com](https://www.contribsys.com)
109
+ Mike Perham, [mastodon](https://ruby.social/@getajobmike), [https://www.mikeperham.com](https://www.mikeperham.com) / [https://www.contribsys.com](https://www.contribsys.com)
data/bin/sidekiqload CHANGED
@@ -28,7 +28,7 @@ require "ruby-prof" if ENV["PROFILE"]
28
28
  require "bundler/setup"
29
29
  Bundler.require(:default, :load_test)
30
30
 
31
- latency = Integer(ENV["LATENCY"] || 1)
31
+ latency = Integer(ENV["LATENCY"] || 0)
32
32
  if latency > 0
33
33
  # brew tap shopify/shopify
34
34
  # brew install toxiproxy
@@ -86,7 +86,7 @@ class Loader
86
86
  def initialize
87
87
  @iter = ENV["GC"] ? 10 : 500
88
88
  @count = Integer(ENV["COUNT"] || 1_000)
89
- @latency = Integer(ENV["LATENCY"] || 1)
89
+ @latency = Integer(ENV["LATENCY"] || 0)
90
90
  end
91
91
 
92
92
  def configure
@@ -137,7 +137,7 @@ class Loader
137
137
  end
138
138
 
139
139
  def setup
140
- Sidekiq.logger.error("Setup RSS: #{Process.rss}")
140
+ Sidekiq.logger.warn("Setup RSS: #{Process.rss}")
141
141
  Sidekiq.redis { |c| c.flushdb }
142
142
  start = Time.now
143
143
  if ENV["AJ"]
@@ -167,9 +167,9 @@ class Loader
167
167
  if total == 0
168
168
  ending = Time.now - @start
169
169
  size = @iter * @count
170
- Sidekiq.logger.error("Done, #{size} jobs in #{ending} sec, #{(size / ending).to_i} jobs/sec")
171
- Sidekiq.logger.error("Ending RSS: #{Process.rss}")
172
- Sidekiq.logger.error("Now here's the latency for three jobs")
170
+ Sidekiq.logger.warn("Done, #{size} jobs in #{ending} sec, #{(size / ending).to_i} jobs/sec")
171
+ Sidekiq.logger.warn("Ending RSS: #{Process.rss}")
172
+ Sidekiq.logger.warn("Now here's the latency for three jobs")
173
173
 
174
174
  if ENV["AJ"]
175
175
  LoadJob.perform_later("", 1, {}, Time.now.to_f)
@@ -191,7 +191,7 @@ class Loader
191
191
  end
192
192
 
193
193
  def with_latency(latency, &block)
194
- Sidekiq.logger.error "Simulating #{latency}ms of latency between Sidekiq and redis"
194
+ Sidekiq.logger.warn "Simulating #{latency}ms of latency between Sidekiq and redis"
195
195
  if latency > 0
196
196
  Toxiproxy[:redis].downstream(:latency, latency: latency).apply(&block)
197
197
  else
@@ -204,8 +204,8 @@ class Loader
204
204
  monitor
205
205
 
206
206
  if ENV["PROFILE"]
207
- RubyProf.exclude_threads = [@monitor]
208
- RubyProf.start
207
+ $profile = RubyProf::Profile.new(exclude_threads: [@monitor])
208
+ $profile.start
209
209
  elsif ENV["GC"]
210
210
  GC.start
211
211
  GC.compact
@@ -236,7 +236,7 @@ class Loader
236
236
  Sidekiq.logger.error("GC End RSS: #{Process.rss}") if ENV["GC"]
237
237
  if ENV["PROFILE"]
238
238
  Sidekiq.logger.error("Profiling...")
239
- result = RubyProf.stop
239
+ result = $profile.stop
240
240
  printer = RubyProf::GraphHtmlPrinter.new(result)
241
241
  printer.print(File.new("output.html", "w"), min_percent: 1)
242
242
  end
data/bin/webload ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler'
4
+ Bundler.setup
5
+
6
+ # This skeleton allows you to run Sidekiq::Web page rendering
7
+ # through Vernier for tuning.
8
+ require "sidekiq/web"
9
+ require "rack/test"
10
+ require "vernier"
11
+
12
+ Sidekiq::Web.configure do |config|
13
+ config.middlewares.clear # remove csrf
14
+ end
15
+
16
+ class SomeJob
17
+ include Sidekiq::Job
18
+ end
19
+
20
+ class BenchWeb
21
+ include Rack::Test::Methods
22
+
23
+ def app
24
+ Sidekiq::Web.new
25
+ end
26
+
27
+ def warmup(page = "/scheduled")
28
+ # Sidekiq.redis {|c| c.flushdb }
29
+
30
+ # 100.times do |idx|
31
+ # SomeJob.perform_at(idx, 1, 3, "mike", {"foo" => "bar"})
32
+ # end
33
+
34
+ 100.times do
35
+ get page
36
+ end
37
+ end
38
+
39
+ def load(page = "/scheduled", count = 10_000)
40
+ profile do
41
+ count.times do
42
+ get page
43
+ raise last_response.inspect unless last_response.status == 200
44
+ end
45
+ end
46
+ end
47
+
48
+ def profile(&)
49
+ if ENV["PROF"]
50
+ Vernier.profile(out: "profile.json.gz", &)
51
+ else
52
+ yield
53
+ end
54
+ end
55
+ end
56
+
57
+ def timer(name="block", count = 10_000)
58
+ a = Time.now
59
+ yield count
60
+ b = Time.now
61
+ puts "#{name} in #{b - a} sec"
62
+ end
63
+
64
+ page = "/busy"
65
+ b = BenchWeb.new
66
+ b.warmup(page)
67
+ timer(page) do |count|
68
+ b.load(page, count)
69
+ end
@@ -1,88 +1,111 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sidekiq
4
- module ActiveJob
5
- # @api private
6
- class Wrapper
7
- include Sidekiq::Job
3
+ begin
4
+ gem "activejob", ">= 7.0"
5
+ require "active_job"
6
+
7
+ module Sidekiq
8
+ module ActiveJob
9
+ # @api private
10
+ class Wrapper
11
+ include Sidekiq::Job
8
12
 
9
- def perform(job_data)
10
- ::ActiveJob::Base.execute(job_data.merge("provider_job_id" => jid))
13
+ def perform(job_data)
14
+ ::ActiveJob::Base.execute(job_data.merge("provider_job_id" => jid))
15
+ end
11
16
  end
12
17
  end
13
18
  end
14
- end
15
-
16
- module ActiveJob
17
- module QueueAdapters
18
- # Explicitly remove the implementation existing in older rails'.
19
- remove_const(:SidekiqAdapter) if const_defined?(:SidekiqAdapter)
20
19
 
21
- # Sidekiq adapter for Active Job
22
- #
23
- # To use Sidekiq set the queue_adapter config to +:sidekiq+.
20
+ unless ActiveJob::Base.respond_to?(:sidekiq_options)
21
+ # By including the Options module, we allow AJs to directly control sidekiq features
22
+ # via the *sidekiq_options* class method and, for instance, not use AJ's retry system.
23
+ # AJ retries don't show up in the Sidekiq UI Retries tab, don't save any error data, can't be
24
+ # manually retried, don't automatically die, etc.
24
25
  #
25
- # Rails.application.config.active_job.queue_adapter = :sidekiq
26
- class SidekiqAdapter
27
- # Defines whether enqueuing should happen implicitly to after commit when called
28
- # from inside a transaction.
29
- # @api private
30
- def enqueue_after_transaction_commit?
31
- true
32
- end
26
+ # class SomeJob < ActiveJob::Base
27
+ # queue_as :default
28
+ # sidekiq_options retry: 3, backtrace: 10
29
+ # def perform
30
+ # end
31
+ # end
32
+ ActiveJob::Base.include Sidekiq::Job::Options
33
+ end
33
34
 
34
- # @api private
35
- def enqueue(job)
36
- job.provider_job_id = JobWrapper.set(
37
- wrapped: job.class,
38
- queue: job.queue_name
39
- ).perform_async(job.serialize)
40
- end
35
+ # Patch the ActiveJob module
36
+ module ActiveJob
37
+ module QueueAdapters
38
+ # Explicitly remove the implementation existing in older Rails.
39
+ remove_const(:SidekiqAdapter) if const_defined?(:SidekiqAdapter)
41
40
 
42
- # @api private
43
- def enqueue_at(job, timestamp)
44
- job.provider_job_id = JobWrapper.set(
45
- wrapped: job.class,
46
- queue: job.queue_name
47
- ).perform_at(timestamp, job.serialize)
48
- end
41
+ # Sidekiq adapter for Active Job
42
+ #
43
+ # To use Sidekiq set the queue_adapter config to +:sidekiq+.
44
+ #
45
+ # Rails.application.config.active_job.queue_adapter = :sidekiq
46
+ class SidekiqAdapter
47
+ # Defines whether enqueuing should happen implicitly to after commit when called
48
+ # from inside a transaction.
49
+ # @api private
50
+ def enqueue_after_transaction_commit?
51
+ true
52
+ end
49
53
 
50
- # @api private
51
- def enqueue_all(jobs)
52
- enqueued_count = 0
53
- jobs.group_by(&:class).each do |job_class, same_class_jobs|
54
- same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
55
- immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
54
+ # @api private
55
+ def enqueue(job)
56
+ job.provider_job_id = Sidekiq::ActiveJob::Wrapper.set(
57
+ wrapped: job.class,
58
+ queue: job.queue_name
59
+ ).perform_async(job.serialize)
60
+ end
56
61
 
57
- if immediate_jobs.any?
58
- jids = Sidekiq::Client.push_bulk(
59
- "class" => JobWrapper,
60
- "wrapped" => job_class,
61
- "queue" => queue,
62
- "args" => immediate_jobs.map { |job| [job.serialize] }
63
- )
64
- enqueued_count += jids.compact.size
65
- end
62
+ # @api private
63
+ def enqueue_at(job, timestamp)
64
+ job.provider_job_id = Sidekiq::ActiveJob::Wrapper.set(
65
+ wrapped: job.class,
66
+ queue: job.queue_name
67
+ ).perform_at(timestamp, job.serialize)
68
+ end
69
+
70
+ # @api private
71
+ def enqueue_all(jobs)
72
+ enqueued_count = 0
73
+ jobs.group_by(&:class).each do |job_class, same_class_jobs|
74
+ same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
75
+ immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
76
+
77
+ if immediate_jobs.any?
78
+ jids = Sidekiq::Client.push_bulk(
79
+ "class" => Sidekiq::ActiveJob::Wrapper,
80
+ "wrapped" => job_class,
81
+ "queue" => queue,
82
+ "args" => immediate_jobs.map { |job| [job.serialize] }
83
+ )
84
+ enqueued_count += jids.compact.size
85
+ end
66
86
 
67
- if scheduled_jobs.any?
68
- jids = Sidekiq::Client.push_bulk(
69
- "class" => JobWrapper,
70
- "wrapped" => job_class,
71
- "queue" => queue,
72
- "args" => scheduled_jobs.map { |job| [job.serialize] },
73
- "at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
74
- )
75
- enqueued_count += jids.compact.size
87
+ if scheduled_jobs.any?
88
+ jids = Sidekiq::Client.push_bulk(
89
+ "class" => Sidekiq::ActiveJob::Wrapper,
90
+ "wrapped" => job_class,
91
+ "queue" => queue,
92
+ "args" => scheduled_jobs.map { |job| [job.serialize] },
93
+ "at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
94
+ )
95
+ enqueued_count += jids.compact.size
96
+ end
76
97
  end
77
98
  end
99
+ enqueued_count
78
100
  end
79
- enqueued_count
80
- end
81
101
 
82
- # Defines a class alias for backwards compatibility with enqueued Active Job jobs.
83
- # @api private
84
- class JobWrapper < Sidekiq::ActiveJob::Wrapper
102
+ # Defines a class alias for backwards compatibility with enqueued Active Job jobs.
103
+ # @api private
104
+ class JobWrapper < Sidekiq::ActiveJob::Wrapper
105
+ end
85
106
  end
86
107
  end
87
108
  end
109
+ rescue Gem::LoadError
110
+ # ActiveJob not available or version requirement not met
88
111
  end