sidekiq 5.1.3 → 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.

Files changed (106) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +391 -1
  3. data/LICENSE +3 -3
  4. data/README.md +23 -34
  5. data/bin/sidekiq +27 -3
  6. data/bin/sidekiqload +68 -62
  7. data/bin/sidekiqmon +8 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +344 -243
  13. data/lib/sidekiq/cli.rb +209 -221
  14. data/lib/sidekiq/client.rb +62 -64
  15. data/lib/sidekiq/delay.rb +7 -6
  16. data/lib/sidekiq/exception_handler.rb +10 -12
  17. data/lib/sidekiq/extensions/action_mailer.rb +13 -22
  18. data/lib/sidekiq/extensions/active_record.rb +13 -10
  19. data/lib/sidekiq/extensions/class_methods.rb +14 -11
  20. data/lib/sidekiq/extensions/generic_proxy.rb +6 -4
  21. data/lib/sidekiq/fetch.rb +40 -32
  22. data/lib/sidekiq/job.rb +13 -0
  23. data/lib/sidekiq/job_logger.rb +35 -9
  24. data/lib/sidekiq/job_retry.rb +88 -68
  25. data/lib/sidekiq/job_util.rb +65 -0
  26. data/lib/sidekiq/launcher.rb +170 -73
  27. data/lib/sidekiq/logger.rb +170 -0
  28. data/lib/sidekiq/manager.rb +18 -22
  29. data/lib/sidekiq/middleware/chain.rb +20 -8
  30. data/lib/sidekiq/middleware/current_attributes.rb +57 -0
  31. data/lib/sidekiq/middleware/i18n.rb +5 -7
  32. data/lib/sidekiq/monitor.rb +133 -0
  33. data/lib/sidekiq/paginator.rb +20 -16
  34. data/lib/sidekiq/processor.rb +135 -83
  35. data/lib/sidekiq/rails.rb +42 -38
  36. data/lib/sidekiq/redis_connection.rb +49 -30
  37. data/lib/sidekiq/scheduled.rb +94 -31
  38. data/lib/sidekiq/sd_notify.rb +149 -0
  39. data/lib/sidekiq/systemd.rb +24 -0
  40. data/lib/sidekiq/testing/inline.rb +2 -1
  41. data/lib/sidekiq/testing.rb +40 -31
  42. data/lib/sidekiq/util.rb +57 -15
  43. data/lib/sidekiq/version.rb +2 -1
  44. data/lib/sidekiq/web/action.rb +15 -11
  45. data/lib/sidekiq/web/application.rb +109 -74
  46. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  47. data/lib/sidekiq/web/helpers.rb +117 -93
  48. data/lib/sidekiq/web/router.rb +23 -19
  49. data/lib/sidekiq/web.rb +61 -105
  50. data/lib/sidekiq/worker.rb +257 -99
  51. data/lib/sidekiq.rb +81 -46
  52. data/sidekiq.gemspec +23 -23
  53. data/web/assets/images/apple-touch-icon.png +0 -0
  54. data/web/assets/javascripts/application.js +83 -64
  55. data/web/assets/javascripts/dashboard.js +66 -75
  56. data/web/assets/stylesheets/application-dark.css +143 -0
  57. data/web/assets/stylesheets/application-rtl.css +0 -4
  58. data/web/assets/stylesheets/application.css +77 -231
  59. data/web/assets/stylesheets/bootstrap.css +2 -2
  60. data/web/locales/ar.yml +9 -2
  61. data/web/locales/de.yml +14 -2
  62. data/web/locales/en.yml +7 -1
  63. data/web/locales/es.yml +21 -5
  64. data/web/locales/fr.yml +10 -3
  65. data/web/locales/ja.yml +7 -1
  66. data/web/locales/lt.yml +83 -0
  67. data/web/locales/pl.yml +4 -4
  68. data/web/locales/ru.yml +4 -0
  69. data/web/locales/vi.yml +83 -0
  70. data/web/views/_footer.erb +1 -1
  71. data/web/views/_job_info.erb +3 -2
  72. data/web/views/_nav.erb +3 -17
  73. data/web/views/_poll_link.erb +2 -5
  74. data/web/views/_summary.erb +7 -7
  75. data/web/views/busy.erb +54 -20
  76. data/web/views/dashboard.erb +22 -14
  77. data/web/views/dead.erb +3 -3
  78. data/web/views/layout.erb +4 -2
  79. data/web/views/morgue.erb +9 -6
  80. data/web/views/queue.erb +20 -10
  81. data/web/views/queues.erb +11 -3
  82. data/web/views/retries.erb +14 -7
  83. data/web/views/retry.erb +3 -3
  84. data/web/views/scheduled.erb +5 -2
  85. metadata +39 -136
  86. data/.github/contributing.md +0 -32
  87. data/.github/issue_template.md +0 -11
  88. data/.gitignore +0 -13
  89. data/.travis.yml +0 -14
  90. data/3.0-Upgrade.md +0 -70
  91. data/4.0-Upgrade.md +0 -53
  92. data/5.0-Upgrade.md +0 -56
  93. data/COMM-LICENSE +0 -95
  94. data/Ent-Changes.md +0 -216
  95. data/Gemfile +0 -8
  96. data/Pro-2.0-Upgrade.md +0 -138
  97. data/Pro-3.0-Upgrade.md +0 -44
  98. data/Pro-4.0-Upgrade.md +0 -35
  99. data/Pro-Changes.md +0 -729
  100. data/Rakefile +0 -8
  101. data/bin/sidekiqctl +0 -99
  102. data/code_of_conduct.md +0 -50
  103. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  104. data/lib/sidekiq/core_ext.rb +0 -1
  105. data/lib/sidekiq/logging.rb +0 -122
  106. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rake/testtask'
3
- Rake::TestTask.new(:test) do |test|
4
- test.warning = true
5
- test.pattern = 'test/**/test_*.rb'
6
- end
7
-
8
- task :default => :test
data/bin/sidekiqctl DELETED
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'fileutils'
4
-
5
- class Sidekiqctl
6
- DEFAULT_KILL_TIMEOUT = 10
7
-
8
- attr_reader :stage, :pidfile, :kill_timeout
9
-
10
- def self.print_usage
11
- puts "#{File.basename($0)} - stop a Sidekiq process from the command line."
12
- puts
13
- puts "Usage: #{File.basename($0)} <command> <pidfile> <kill_timeout>"
14
- puts " where <command> is either 'quiet' or 'stop'"
15
- puts " <pidfile> is path to a pidfile"
16
- puts " <kill_timeout> is number of seconds to wait until Sidekiq exits"
17
- puts " (default: #{Sidekiqctl::DEFAULT_KILL_TIMEOUT}), after which Sidekiq will be KILL'd"
18
- puts
19
- puts "Be sure to set the kill_timeout LONGER than Sidekiq's -t timeout. If you want"
20
- puts "to wait 60 seconds for jobs to finish, use `sidekiq -t 60` and `sidekiqctl stop"
21
- puts " path_to_pidfile 61`"
22
- puts
23
- end
24
-
25
- def initialize(stage, pidfile, timeout)
26
- @stage = stage
27
- @pidfile = pidfile
28
- @kill_timeout = timeout
29
-
30
- done('No pidfile given', :error) if !pidfile
31
- done("Pidfile #{pidfile} does not exist", :warn) if !File.exist?(pidfile)
32
- done('Invalid pidfile content', :error) if pid == 0
33
-
34
- fetch_process
35
-
36
- begin
37
- send(stage)
38
- rescue NoMethodError
39
- done "Invalid command: #{stage}", :error
40
- end
41
- end
42
-
43
- def fetch_process
44
- Process.kill(0, pid)
45
- rescue Errno::ESRCH
46
- done "Process doesn't exist", :error
47
- # We were not allowed to send a signal, but the process must have existed
48
- # when Process.kill() was called.
49
- rescue Errno::EPERM
50
- return pid
51
- end
52
-
53
- def done(msg, error = nil)
54
- puts msg
55
- exit(exit_signal(error))
56
- end
57
-
58
- def exit_signal(error)
59
- (error == :error) ? 1 : 0
60
- end
61
-
62
- def pid
63
- @pid ||= File.read(pidfile).to_i
64
- end
65
-
66
- def quiet
67
- `kill -TSTP #{pid}`
68
- end
69
-
70
- def stop
71
- `kill -TERM #{pid}`
72
- kill_timeout.times do
73
- begin
74
- Process.kill(0, pid)
75
- rescue Errno::ESRCH
76
- FileUtils.rm_f pidfile
77
- done 'Sidekiq shut down gracefully.'
78
- rescue Errno::EPERM
79
- done 'Not permitted to shut down Sidekiq.'
80
- end
81
- sleep 1
82
- end
83
- `kill -9 #{pid}`
84
- FileUtils.rm_f pidfile
85
- done 'Sidekiq shut down forcefully.'
86
- end
87
- alias_method :shutdown, :stop
88
- end
89
-
90
- if ARGV.length < 2
91
- Sidekiqctl.print_usage
92
- else
93
- stage = ARGV[0]
94
- pidfile = ARGV[1]
95
- timeout = ARGV[2].to_i
96
- timeout = Sidekiqctl::DEFAULT_KILL_TIMEOUT if timeout == 0
97
-
98
- Sidekiqctl.new(stage, pidfile, timeout)
99
- end
data/code_of_conduct.md DELETED
@@ -1,50 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, and in the interest of
4
- fostering an open and welcoming community, we pledge to respect all people who
5
- contribute through reporting issues, posting feature requests, updating
6
- documentation, submitting pull requests or patches, and other activities.
7
-
8
- We are committed to making participation in this project a harassment-free
9
- experience for everyone, regardless of level of experience, gender, gender
10
- identity and expression, sexual orientation, disability, personal appearance,
11
- body size, race, ethnicity, age, religion, or nationality.
12
-
13
- Examples of unacceptable behavior by participants include:
14
-
15
- * The use of sexualized language or imagery
16
- * Personal attacks
17
- * Trolling or insulting/derogatory comments
18
- * Public or private harassment
19
- * Publishing other's private information, such as physical or electronic
20
- addresses, without explicit permission
21
- * Other unethical or unprofessional conduct
22
-
23
- Project maintainers have the right and responsibility to remove, edit, or
24
- reject comments, commits, code, wiki edits, issues, and other contributions
25
- that are not aligned to this Code of Conduct, or to ban temporarily or
26
- permanently any contributor for other behaviors that they deem inappropriate,
27
- threatening, offensive, or harmful.
28
-
29
- By adopting this Code of Conduct, project maintainers commit themselves to
30
- fairly and consistently applying these principles to every aspect of managing
31
- this project. Project maintainers who do not follow or enforce the Code of
32
- Conduct may be permanently removed from the project team.
33
-
34
- This Code of Conduct applies both within project spaces and in public spaces
35
- when an individual is representing the project or its community.
36
-
37
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting the project maintainer at mperham AT gmail.com. All
39
- complaints will be reviewed and investigated and will result in a response that
40
- is deemed necessary and appropriate to the circumstances. Maintainers are
41
- obligated to maintain confidentiality with regard to the reporter of an
42
- incident.
43
-
44
-
45
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
46
- version 1.3.0, available at
47
- [http://contributor-covenant.org/version/1/3/0/][version]
48
-
49
- [homepage]: http://contributor-covenant.org
50
- [version]: http://contributor-covenant.org/version/1/3/0/
@@ -1,49 +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
- if defined?(RSpec)
20
- create_worker_spec
21
- else
22
- create_worker_test
23
- end
24
- end
25
-
26
- private
27
-
28
- def create_worker_spec
29
- template_file = File.join(
30
- 'spec/workers',
31
- class_path,
32
- "#{file_name}_worker_spec.rb"
33
- )
34
- template 'worker_spec.rb.erb', template_file
35
- end
36
-
37
- def create_worker_test
38
- template_file = File.join(
39
- 'test/workers',
40
- class_path,
41
- "#{file_name}_worker_test.rb"
42
- )
43
- template 'worker_test.rb.erb', template_file
44
- end
45
-
46
-
47
- end
48
- end
49
- end
@@ -1 +0,0 @@
1
- raise "no longer used, will be removed in 5.1"
@@ -1,122 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'time'
3
- require 'logger'
4
- require 'fcntl'
5
-
6
- module Sidekiq
7
- module Logging
8
-
9
- class Pretty < Logger::Formatter
10
- SPACE = " "
11
-
12
- # Provide a call() method that returns the formatted message.
13
- def call(severity, time, program_name, message)
14
- "#{time.utc.iso8601(3)} #{::Process.pid} TID-#{Sidekiq::Logging.tid}#{context} #{severity}: #{message}\n"
15
- end
16
-
17
- def context
18
- c = Thread.current[:sidekiq_context]
19
- " #{c.join(SPACE)}" if c && c.any?
20
- end
21
- end
22
-
23
- class WithoutTimestamp < Pretty
24
- def call(severity, time, program_name, message)
25
- "#{::Process.pid} TID-#{Sidekiq::Logging.tid}#{context} #{severity}: #{message}\n"
26
- end
27
- end
28
-
29
- def self.tid
30
- Thread.current['sidekiq_tid'] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
31
- end
32
-
33
- def self.job_hash_context(job_hash)
34
- # If we're using a wrapper class, like ActiveJob, use the "wrapped"
35
- # attribute to expose the underlying thing.
36
- klass = job_hash['wrapped'] || job_hash["class"]
37
- bid = job_hash['bid']
38
- "#{klass} JID-#{job_hash['jid']}#{" BID-#{bid}" if bid}"
39
- end
40
-
41
- def self.with_job_hash_context(job_hash, &block)
42
- with_context(job_hash_context(job_hash), &block)
43
- end
44
-
45
- def self.with_context(msg)
46
- Thread.current[:sidekiq_context] ||= []
47
- Thread.current[:sidekiq_context] << msg
48
- yield
49
- ensure
50
- Thread.current[:sidekiq_context].pop
51
- end
52
-
53
- def self.initialize_logger(log_target = STDOUT)
54
- oldlogger = defined?(@logger) ? @logger : nil
55
- @logger = Logger.new(log_target)
56
- @logger.level = Logger::INFO
57
- @logger.formatter = ENV['DYNO'] ? WithoutTimestamp.new : Pretty.new
58
- oldlogger.close if oldlogger && !$TESTING # don't want to close testing's STDOUT logging
59
- @logger
60
- end
61
-
62
- def self.logger
63
- defined?(@logger) ? @logger : initialize_logger
64
- end
65
-
66
- def self.logger=(log)
67
- @logger = (log ? log : Logger.new(File::NULL))
68
- end
69
-
70
- # This reopens ALL logfiles in the process that have been rotated
71
- # using logrotate(8) (without copytruncate) or similar tools.
72
- # A +File+ object is considered for reopening if it is:
73
- # 1) opened with the O_APPEND and O_WRONLY flags
74
- # 2) the current open file handle does not match its original open path
75
- # 3) unbuffered (as far as userspace buffering goes, not O_SYNC)
76
- # Returns the number of files reopened
77
- def self.reopen_logs
78
- to_reopen = []
79
- append_flags = File::WRONLY | File::APPEND
80
-
81
- ObjectSpace.each_object(File) do |fp|
82
- begin
83
- if !fp.closed? && fp.stat.file? && fp.sync && (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
84
- to_reopen << fp
85
- end
86
- rescue IOError, Errno::EBADF
87
- end
88
- end
89
-
90
- nr = 0
91
- to_reopen.each do |fp|
92
- orig_st = begin
93
- fp.stat
94
- rescue IOError, Errno::EBADF
95
- next
96
- end
97
-
98
- begin
99
- b = File.stat(fp.path)
100
- next if orig_st.ino == b.ino && orig_st.dev == b.dev
101
- rescue Errno::ENOENT
102
- end
103
-
104
- begin
105
- File.open(fp.path, 'a') { |tmpfp| fp.reopen(tmpfp) }
106
- fp.sync = true
107
- nr += 1
108
- rescue IOError, Errno::EBADF
109
- # not much we can do...
110
- end
111
- end
112
- nr
113
- rescue RuntimeError => ex
114
- # RuntimeError: ObjectSpace is disabled; each_object will only work with Class, pass -X+O to enable
115
- puts "Unable to reopen logs: #{ex.message}"
116
- end
117
-
118
- def logger
119
- Sidekiq::Logging.logger
120
- end
121
- end
122
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
- module Sidekiq
3
- module Middleware
4
- module Server
5
- class ActiveRecord
6
-
7
- def initialize
8
- # With Rails 5+ we must use the Reloader **always**.
9
- # The reloader handles code loading and db connection management.
10
- if defined?(::Rails) && ::Rails::VERSION::MAJOR >= 5
11
- raise ArgumentError, "Rails 5 no longer needs or uses the ActiveRecord middleware."
12
- end
13
- end
14
-
15
- def call(*args)
16
- yield
17
- ensure
18
- ::ActiveRecord::Base.clear_active_connections!
19
- end
20
- end
21
- end
22
- end
23
- end