sidekiq 7.3.6 → 8.0.0

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 +60 -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 +5 -18
  7. data/lib/sidekiq/api.rb +120 -36
  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 +62 -2
  12. data/lib/sidekiq/config.rb +24 -15
  13. data/lib/sidekiq/embedded.rb +1 -0
  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 +1 -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 +14 -1
  27. data/lib/sidekiq/processor.rb +21 -14
  28. data/lib/sidekiq/profiler.rb +59 -0
  29. data/lib/sidekiq/rails.rb +12 -2
  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 +105 -73
  35. data/lib/sidekiq/web/application.rb +347 -332
  36. data/lib/sidekiq/web/config.rb +117 -0
  37. data/lib/sidekiq/web/helpers.rb +49 -23
  38. data/lib/sidekiq/web/router.rb +60 -76
  39. data/lib/sidekiq/web.rb +51 -152
  40. data/lib/sidekiq.rb +1 -1
  41. data/sidekiq.gemspec +6 -5
  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 +750 -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 +1 -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 +6 -22
  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 +35 -24
  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
@@ -1,103 +1,135 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "erb"
4
+
3
5
  module Sidekiq
4
- class WebAction
5
- RACK_SESSION = "rack.session"
6
+ class Web
7
+ ##
8
+ # These instance methods are available to all executing ERB
9
+ # templates.
10
+ class Action
11
+ attr_accessor :env, :block
12
+
13
+ def initialize(env, block)
14
+ @_erb = false
15
+ @env = env
16
+ @block = block
17
+ end
6
18
 
7
- attr_accessor :env, :block, :type
19
+ def config
20
+ env[:web_config]
21
+ end
8
22
 
9
- def settings
10
- Web.settings
11
- end
23
+ def request
24
+ @request ||= ::Rack::Request.new(env)
25
+ end
12
26
 
13
- def request
14
- @request ||= ::Rack::Request.new(env)
15
- end
27
+ def halt(res)
28
+ throw :halt, [res, {"content-type" => "text/plain"}, [res.to_s]]
29
+ end
16
30
 
17
- def halt(res)
18
- throw :halt, [res, {Rack::CONTENT_TYPE => "text/plain"}, [res.to_s]]
19
- end
31
+ # external redirect
32
+ def redirect_to(url)
33
+ throw :halt, [302, {"Location" => url}, []]
34
+ end
20
35
 
21
- def redirect(location)
22
- throw :halt, [302, {Web::LOCATION => "#{request.base_url}#{location}"}, []]
23
- end
36
+ def header(key, value)
37
+ env["response_headers"][key] = value
38
+ end
24
39
 
25
- def reload_page
26
- current_location = request.referer.gsub(request.base_url, "")
27
- redirect current_location
28
- end
40
+ # internal redirect
41
+ def redirect(location)
42
+ throw :halt, [302, {"Location" => "#{request.base_url}#{location}"}, []]
43
+ end
29
44
 
30
- def params
31
- indifferent_hash = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
45
+ def reload_page
46
+ current_location = request.referer.gsub(request.base_url, "")
47
+ redirect current_location
48
+ end
32
49
 
33
- indifferent_hash.merge! request.params
34
- route_params.each { |k, v| indifferent_hash[k.to_s] = v }
50
+ # stuff after ? or form input
51
+ # uses String keys, no Symbols!
52
+ def url_params(key)
53
+ warn { "URL parameter `#{key}` should be accessed via String, not Symbol (at #{caller(3..3).first})" } if key.is_a?(Symbol)
54
+ request.params[key.to_s]
55
+ end
35
56
 
36
- indifferent_hash
37
- end
57
+ # variables embedded in path, `/metrics/:name`
58
+ # uses Symbol keys, no Strings!
59
+ def route_params(key)
60
+ warn { "Route parameter `#{key}` should be accessed via Symbol, not String (at #{caller(3..3).first})" } if key.is_a?(String)
61
+ env["rack.route_params"][key.to_sym]
62
+ end
38
63
 
39
- def route_params
40
- env[WebRouter::ROUTE_PARAMS]
41
- end
64
+ def params
65
+ warn { "Direct access to Rack parameters is discouraged, use `url_params` or `route_params` (at #{caller(3..3).first})" }
66
+ request.params
67
+ end
42
68
 
43
- def session
44
- env[RACK_SESSION]
45
- end
69
+ def session
70
+ env["rack.session"]
71
+ end
46
72
 
47
- def erb(content, options = {})
48
- if content.is_a? Symbol
49
- unless respond_to?(:"_erb_#{content}")
50
- views = options[:views] || Web.settings.views
51
- filename = "#{views}/#{content}.erb"
52
- src = ERB.new(File.read(filename)).src
53
-
54
- # Need to use lineno less by 1 because erb generates a
55
- # comment before the source code.
56
- WebAction.class_eval <<-RUBY, filename, -1 # standard:disable Style/EvalWithLocation
57
- def _erb_#{content}
58
- #{src}
59
- end
60
- RUBY
73
+ def erb(content, options = {})
74
+ if content.is_a? Symbol
75
+ unless respond_to?(:"_erb_#{content}")
76
+ views = options[:views] || Web.views
77
+ filename = "#{views}/#{content}.erb"
78
+ src = ERB.new(File.read(filename)).src
79
+
80
+ # Need to use lineno less by 1 because erb generates a
81
+ # comment before the source code.
82
+ Action.class_eval <<-RUBY, filename, -1 # standard:disable Style/EvalWithLocation
83
+ def _erb_#{content}
84
+ #{src}
85
+ end
86
+ RUBY
87
+ end
61
88
  end
62
- end
63
89
 
64
- if @_erb
65
- _erb(content, options[:locals])
66
- else
67
- @_erb = true
68
- content = _erb(content, options[:locals])
90
+ if @_erb
91
+ _erb(content, options[:locals])
92
+ else
93
+ @_erb = true
94
+ content = _erb(content, options[:locals])
69
95
 
70
- _render { content }
96
+ _render { content }
97
+ end
71
98
  end
72
- end
73
99
 
74
- def render(engine, content, options = {})
75
- raise "Only erb templates are supported" if engine != :erb
100
+ def render(engine, content, options = {})
101
+ raise "Only erb templates are supported" if engine != :erb
76
102
 
77
- erb(content, options)
78
- end
103
+ erb(content, options)
104
+ end
79
105
 
80
- def json(payload)
81
- [200, {Rack::CONTENT_TYPE => "application/json", Rack::CACHE_CONTROL => "private, no-store"}, [Sidekiq.dump_json(payload)]]
82
- end
106
+ def json(payload)
107
+ [200,
108
+ {"content-type" => "application/json", "cache-control" => "private, no-store"},
109
+ [Sidekiq.dump_json(payload)]]
110
+ end
83
111
 
84
- def initialize(env, block)
85
- @_erb = false
86
- @env = env
87
- @block = block
88
- @files ||= {}
89
- end
112
+ private
90
113
 
91
- private
114
+ def warn
115
+ Sidekiq.logger.warn yield
116
+ end
92
117
 
93
- def _erb(file, locals)
94
- locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
118
+ def _erb(file, locals)
119
+ locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
95
120
 
96
- if file.is_a?(String)
97
- ERB.new(file).result(binding)
98
- else
99
- send(:"_erb_#{file}")
121
+ if file.is_a?(String)
122
+ ERB.new(file).result(binding)
123
+ else
124
+ send(:"_erb_#{file}")
125
+ end
100
126
  end
127
+
128
+ class_eval <<-RUBY, ::Sidekiq::Web::LAYOUT, -1 # standard:disable Style/EvalWithLocation
129
+ def _render
130
+ #{ERB.new(File.read(::Sidekiq::Web::LAYOUT)).src}
131
+ end
132
+ RUBY
101
133
  end
102
134
  end
103
135
  end