sidekiq 7.3.9 → 8.1.7

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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +225 -0
  3. data/README.md +34 -14
  4. data/bin/kiq +17 -0
  5. data/bin/lint-herb +13 -0
  6. data/bin/sidekiqload +12 -10
  7. data/bin/webload +69 -0
  8. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +107 -58
  9. data/lib/generators/sidekiq/job_generator.rb +15 -3
  10. data/lib/generators/sidekiq/templates/job.rb.erb +1 -1
  11. data/lib/sidekiq/api.rb +310 -83
  12. data/lib/sidekiq/capsule.rb +10 -7
  13. data/lib/sidekiq/cli.rb +31 -24
  14. data/lib/sidekiq/client.rb +36 -18
  15. data/lib/sidekiq/component.rb +45 -3
  16. data/lib/sidekiq/config.rb +35 -30
  17. data/lib/sidekiq/embedded.rb +2 -1
  18. data/lib/sidekiq/fetch.rb +1 -0
  19. data/lib/sidekiq/iterable_job.rb +1 -0
  20. data/lib/sidekiq/job/iterable.rb +46 -18
  21. data/lib/sidekiq/job.rb +18 -3
  22. data/lib/sidekiq/job_logger.rb +8 -6
  23. data/lib/sidekiq/job_retry.rb +45 -18
  24. data/lib/sidekiq/job_util.rb +5 -1
  25. data/lib/sidekiq/launcher.rb +22 -12
  26. data/lib/sidekiq/loader.rb +57 -0
  27. data/lib/sidekiq/logger.rb +25 -69
  28. data/lib/sidekiq/manager.rb +2 -2
  29. data/lib/sidekiq/metrics/query.rb +77 -46
  30. data/lib/sidekiq/metrics/shared.rb +8 -5
  31. data/lib/sidekiq/metrics/tracking.rb +12 -7
  32. data/lib/sidekiq/middleware/current_attributes.rb +11 -19
  33. data/lib/sidekiq/middleware/i18n.rb +2 -0
  34. data/lib/sidekiq/monitor.rb +4 -8
  35. data/lib/sidekiq/paginator.rb +18 -2
  36. data/lib/sidekiq/processor.rb +26 -18
  37. data/lib/sidekiq/profiler.rb +73 -0
  38. data/lib/sidekiq/rails.rb +46 -67
  39. data/lib/sidekiq/redis_client_adapter.rb +6 -3
  40. data/lib/sidekiq/redis_connection.rb +16 -5
  41. data/lib/sidekiq/ring_buffer.rb +1 -0
  42. data/lib/sidekiq/scheduled.rb +6 -7
  43. data/lib/sidekiq/test_api.rb +331 -0
  44. data/lib/sidekiq/testing/inline.rb +2 -30
  45. data/lib/sidekiq/testing.rb +2 -333
  46. data/lib/sidekiq/transaction_aware_client.rb +13 -5
  47. data/lib/sidekiq/tui/controls.rb +53 -0
  48. data/lib/sidekiq/tui/filtering.rb +53 -0
  49. data/lib/sidekiq/tui/tabs/base_tab.rb +230 -0
  50. data/lib/sidekiq/tui/tabs/busy.rb +104 -0
  51. data/lib/sidekiq/tui/tabs/dead.rb +14 -0
  52. data/lib/sidekiq/tui/tabs/home.rb +115 -0
  53. data/lib/sidekiq/tui/tabs/metrics.rb +114 -0
  54. data/lib/sidekiq/tui/tabs/queues.rb +83 -0
  55. data/lib/sidekiq/tui/tabs/retries.rb +14 -0
  56. data/lib/sidekiq/tui/tabs/scheduled.rb +14 -0
  57. data/lib/sidekiq/tui/tabs/set_tab.rb +91 -0
  58. data/lib/sidekiq/tui/tabs.rb +15 -0
  59. data/lib/sidekiq/tui.rb +390 -0
  60. data/lib/sidekiq/version.rb +2 -2
  61. data/lib/sidekiq/web/action.rb +146 -83
  62. data/lib/sidekiq/web/application.rb +372 -328
  63. data/lib/sidekiq/web/config.rb +117 -0
  64. data/lib/sidekiq/web/helpers.rb +102 -44
  65. data/lib/sidekiq/web/router.rb +61 -77
  66. data/lib/sidekiq/web.rb +65 -151
  67. data/lib/sidekiq.rb +13 -1
  68. data/sidekiq.gemspec +9 -8
  69. data/web/assets/images/logo.png +0 -0
  70. data/web/assets/images/status.png +0 -0
  71. data/web/assets/javascripts/application.js +43 -27
  72. data/web/assets/javascripts/base-charts.js +30 -16
  73. data/web/assets/javascripts/chartjs-adapter-date-fns.min.js +7 -0
  74. data/web/assets/javascripts/dashboard.js +1 -1
  75. data/web/assets/javascripts/metrics.js +16 -34
  76. data/web/assets/stylesheets/style.css +776 -0
  77. data/web/locales/ar.yml +3 -1
  78. data/web/locales/cs.yml +2 -0
  79. data/web/locales/da.yml +2 -0
  80. data/web/locales/de.yml +2 -0
  81. data/web/locales/el.yml +2 -0
  82. data/web/locales/en.yml +8 -0
  83. data/web/locales/es.yml +25 -2
  84. data/web/locales/fa.yml +3 -1
  85. data/web/locales/fr.yml +3 -1
  86. data/web/locales/gd.yml +13 -1
  87. data/web/locales/he.yml +3 -1
  88. data/web/locales/hi.yml +36 -0
  89. data/web/locales/it.yml +9 -0
  90. data/web/locales/ja.yml +2 -0
  91. data/web/locales/ko.yml +2 -0
  92. data/web/locales/lt.yml +2 -0
  93. data/web/locales/nb.yml +2 -0
  94. data/web/locales/nl.yml +2 -0
  95. data/web/locales/pl.yml +2 -0
  96. data/web/locales/{pt-br.yml → pt-BR.yml} +3 -1
  97. data/web/locales/pt.yml +2 -0
  98. data/web/locales/ru.yml +2 -0
  99. data/web/locales/sv.yml +2 -0
  100. data/web/locales/ta.yml +83 -47
  101. data/web/locales/tr.yml +2 -0
  102. data/web/locales/uk.yml +7 -5
  103. data/web/locales/ur.yml +3 -1
  104. data/web/locales/vi.yml +2 -0
  105. data/web/locales/{zh-cn.yml → zh-CN.yml} +86 -73
  106. data/web/locales/{zh-tw.yml → zh-TW.yml} +3 -1
  107. data/web/views/_footer.html.erb +32 -0
  108. data/web/views/_job_info.html.erb +115 -0
  109. data/web/views/_metrics_period_select.html.erb +15 -0
  110. data/web/views/_nav.html.erb +45 -0
  111. data/web/views/_paging.html.erb +26 -0
  112. data/web/views/_poll_link.html.erb +4 -0
  113. data/web/views/{_summary.erb → _summary.html.erb} +16 -16
  114. data/web/views/busy.html.erb +155 -0
  115. data/web/views/dashboard.html.erb +104 -0
  116. data/web/views/dead.html.erb +38 -0
  117. data/web/views/filtering.html.erb +6 -0
  118. data/web/views/layout.html.erb +26 -0
  119. data/web/views/metrics.html.erb +85 -0
  120. data/web/views/metrics_for_job.html.erb +58 -0
  121. data/web/views/morgue.html.erb +69 -0
  122. data/web/views/profiles.html.erb +43 -0
  123. data/web/views/queue.html.erb +57 -0
  124. data/web/views/queues.html.erb +46 -0
  125. data/web/views/retries.html.erb +77 -0
  126. data/web/views/retry.html.erb +39 -0
  127. data/web/views/scheduled.html.erb +64 -0
  128. data/web/views/{scheduled_job_info.erb → scheduled_job_info.html.erb} +3 -3
  129. metadata +65 -47
  130. data/lib/sidekiq/web/csrf_protection.rb +0 -183
  131. data/web/assets/stylesheets/application-dark.css +0 -147
  132. data/web/assets/stylesheets/application-rtl.css +0 -163
  133. data/web/assets/stylesheets/application.css +0 -759
  134. data/web/assets/stylesheets/bootstrap-rtl.min.css +0 -9
  135. data/web/assets/stylesheets/bootstrap.css +0 -5
  136. data/web/views/_footer.erb +0 -34
  137. data/web/views/_job_info.erb +0 -105
  138. data/web/views/_metrics_period_select.erb +0 -12
  139. data/web/views/_nav.erb +0 -52
  140. data/web/views/_paging.erb +0 -25
  141. data/web/views/_poll_link.erb +0 -4
  142. data/web/views/_status.erb +0 -4
  143. data/web/views/busy.erb +0 -148
  144. data/web/views/dashboard.erb +0 -108
  145. data/web/views/dead.erb +0 -34
  146. data/web/views/filtering.erb +0 -6
  147. data/web/views/layout.erb +0 -42
  148. data/web/views/metrics.erb +0 -90
  149. data/web/views/metrics_for_job.erb +0 -59
  150. data/web/views/morgue.erb +0 -74
  151. data/web/views/queue.erb +0 -55
  152. data/web/views/queues.erb +0 -44
  153. data/web/views/retries.erb +0 -79
  154. data/web/views/retry.erb +0 -34
  155. data/web/views/scheduled.erb +0 -56
@@ -1,75 +1,124 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveJob
4
- module QueueAdapters
5
- # Explicitly remove the implementation existing in older rails'.
6
- remove_const(:SidekiqAdapter) if const_defined?(:SidekiqAdapter)
3
+ begin
4
+ gem "activejob", ">= 7.0"
5
+ require "active_job"
7
6
 
8
- # Sidekiq adapter for Active Job
9
- #
10
- # To use Sidekiq set the queue_adapter config to +:sidekiq+.
11
- #
12
- # Rails.application.config.active_job.queue_adapter = :sidekiq
13
- class SidekiqAdapter
14
- # Defines whether enqueuing should happen implicitly to after commit when called
15
- # from inside a transaction.
7
+ module Sidekiq
8
+ module ActiveJob
16
9
  # @api private
17
- def enqueue_after_transaction_commit?
18
- true
19
- end
10
+ class Wrapper
11
+ include Sidekiq::Job
20
12
 
21
- # @api private
22
- def enqueue(job)
23
- job.provider_job_id = JobWrapper.set(
24
- wrapped: job.class,
25
- queue: job.queue_name
26
- ).perform_async(job.serialize)
13
+ def perform(job_data)
14
+ ::ActiveJob::Base.execute(job_data.merge("provider_job_id" => jid))
15
+ end
27
16
  end
17
+ end
18
+ end
28
19
 
29
- # @api private
30
- def enqueue_at(job, timestamp)
31
- job.provider_job_id = JobWrapper.set(
32
- wrapped: job.class,
33
- queue: job.queue_name
34
- ).perform_at(timestamp, job.serialize)
35
- end
20
+ ActiveSupport.on_load(:active_job) do
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.
25
+ #
26
+ # class SomeJob < ActiveJob::Base
27
+ # queue_as :default
28
+ # sidekiq_options retry: 3, backtrace: 10
29
+ # def perform
30
+ # end
31
+ # end
32
+ include Sidekiq::Job::Options unless respond_to?(:sidekiq_options)
33
+ end
36
34
 
37
- # @api private
38
- def enqueue_all(jobs)
39
- enqueued_count = 0
40
- jobs.group_by(&:class).each do |job_class, same_class_jobs|
41
- same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
42
- immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
43
-
44
- if immediate_jobs.any?
45
- jids = Sidekiq::Client.push_bulk(
46
- "class" => JobWrapper,
47
- "wrapped" => job_class,
48
- "queue" => queue,
49
- "args" => immediate_jobs.map { |job| [job.serialize] }
50
- )
51
- enqueued_count += jids.compact.size
52
- 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)
40
+
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
+ parent = const_defined?(:AbstractAdapter) ? AbstractAdapter : Object
47
+ class SidekiqAdapter < parent
48
+ @@stopping = false
49
+
50
+ callback = -> { @@stopping = true }
53
51
 
54
- if scheduled_jobs.any?
55
- jids = Sidekiq::Client.push_bulk(
56
- "class" => JobWrapper,
57
- "wrapped" => job_class,
58
- "queue" => queue,
59
- "args" => scheduled_jobs.map { |job| [job.serialize] },
60
- "at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
61
- )
62
- enqueued_count += jids.compact.size
52
+ Sidekiq.configure_client { |config| config.on(:quiet, &callback) }
53
+ Sidekiq.configure_server { |config| config.on(:quiet, &callback) }
54
+
55
+ # Defines whether enqueuing should happen implicitly to after commit when called
56
+ # from inside a transaction.
57
+ # @api private
58
+ def enqueue_after_transaction_commit?
59
+ true
60
+ end
61
+
62
+ # @api private
63
+ def enqueue(job)
64
+ # NB: Active Job only serializes keys it recognizes. We
65
+ # cannot set arbitrary key/values here.
66
+ options = {wrapped: job.class, queue: job.queue_name}
67
+ options[:profile] = job.profile if job.respond_to?(:profile) && !job.profile.nil?
68
+
69
+ wrapper = Sidekiq::ActiveJob::Wrapper.set(options)
70
+ job.provider_job_id = wrapper.perform_async(job.serialize)
71
+ end
72
+
73
+ # @api private
74
+ def enqueue_at(job, timestamp)
75
+ options = {wrapped: job.class, queue: job.queue_name}
76
+ options[:profile] = job.profile if job.respond_to?(:profile) && !job.profile.nil?
77
+
78
+ job.provider_job_id = Sidekiq::ActiveJob::Wrapper.set(options).perform_at(timestamp, job.serialize)
79
+ end
80
+
81
+ # @api private
82
+ def enqueue_all(jobs)
83
+ enqueued_count = 0
84
+ jobs.group_by(&:class).each do |job_class, same_class_jobs|
85
+ same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
86
+ immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
87
+
88
+ if immediate_jobs.any?
89
+ jids = Sidekiq::Client.push_bulk(
90
+ "class" => Sidekiq::ActiveJob::Wrapper,
91
+ "wrapped" => job_class,
92
+ "queue" => queue,
93
+ "args" => immediate_jobs.map { |job| [job.serialize] }
94
+ )
95
+ enqueued_count += jids.compact.size
96
+ end
97
+
98
+ if scheduled_jobs.any?
99
+ jids = Sidekiq::Client.push_bulk(
100
+ "class" => Sidekiq::ActiveJob::Wrapper,
101
+ "wrapped" => job_class,
102
+ "queue" => queue,
103
+ "args" => scheduled_jobs.map { |job| [job.serialize] },
104
+ "at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
105
+ )
106
+ enqueued_count += jids.compact.size
107
+ end
63
108
  end
64
109
  end
110
+ enqueued_count
65
111
  end
66
- enqueued_count
67
- end
68
112
 
69
- # Defines a class alias for backwards compatibility with enqueued Active Job jobs.
70
- # @api private
71
- class JobWrapper < Sidekiq::ActiveJob::Wrapper
113
+ # @api private
114
+ def stopping?(job = nil) = !!@@stopping
115
+
116
+ # Defines a class alias for backwards compatibility with enqueued Active Job jobs.
117
+ # @api private
118
+ JobWrapper = Sidekiq::ActiveJob::Wrapper
72
119
  end
73
120
  end
74
121
  end
122
+ rescue Gem::LoadError
123
+ # ActiveJob not available or version requirement not met
75
124
  end
@@ -14,7 +14,10 @@ module Sidekiq
14
14
  end
15
15
 
16
16
  def create_job_file
17
- template "job.rb.erb", File.join("app/sidekiq", class_path, "#{file_name}_job.rb")
17
+ template(
18
+ "job.rb.erb",
19
+ File.join(jobs_directory, class_path, "#{file_name}_job.rb")
20
+ )
18
21
  end
19
22
 
20
23
  def create_test_file
@@ -31,7 +34,8 @@ module Sidekiq
31
34
 
32
35
  def create_job_spec
33
36
  template_file = File.join(
34
- "spec/sidekiq",
37
+ "spec",
38
+ jobs_directory.gsub("app/", ""),
35
39
  class_path,
36
40
  "#{file_name}_job_spec.rb"
37
41
  )
@@ -40,7 +44,8 @@ module Sidekiq
40
44
 
41
45
  def create_job_test
42
46
  template_file = File.join(
43
- "test/sidekiq",
47
+ "test",
48
+ jobs_directory.gsub("app/", ""),
44
49
  class_path,
45
50
  "#{file_name}_job_test.rb"
46
51
  )
@@ -54,6 +59,13 @@ module Sidekiq
54
59
  def test_framework
55
60
  ::Rails.application.config.generators.options[:rails][:test_framework]
56
61
  end
62
+
63
+ # Can be set in an initializer or in application configuration
64
+ # with Rails.application.config.generators.options[:sidekiq][:jobs_directory] = "app/jobs"
65
+ # to change the directory that the job files are generated in to.
66
+ def jobs_directory
67
+ ::Rails.application.config.generators.options[:sidekiq].fetch(:jobs_directory, "app/sidekiq")
68
+ end
57
69
  end
58
70
  end
59
71
  end
@@ -6,4 +6,4 @@ class <%= class_name %>Job
6
6
  # Do something
7
7
  end
8
8
  end
9
- <% end -%>
9
+ <% end -%>