sidekiq 5.1.1 → 7.1.2
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 +5 -5
- data/Changes.md +627 -8
- data/LICENSE.txt +9 -0
- data/README.md +47 -50
- data/bin/sidekiq +22 -3
- data/bin/sidekiqload +213 -115
- data/bin/sidekiqmon +11 -0
- data/lib/generators/sidekiq/job_generator.rb +57 -0
- data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
- data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
- data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
- data/lib/sidekiq/api.rb +566 -329
- data/lib/sidekiq/capsule.rb +127 -0
- data/lib/sidekiq/cli.rb +241 -256
- data/lib/sidekiq/client.rb +125 -102
- data/lib/sidekiq/component.rb +68 -0
- data/lib/sidekiq/config.rb +278 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +49 -42
- data/lib/sidekiq/job.rb +374 -0
- data/lib/sidekiq/job_logger.rb +36 -9
- data/lib/sidekiq/job_retry.rb +147 -98
- data/lib/sidekiq/job_util.rb +105 -0
- data/lib/sidekiq/launcher.rb +207 -103
- data/lib/sidekiq/logger.rb +131 -0
- data/lib/sidekiq/manager.rb +43 -47
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +136 -0
- data/lib/sidekiq/middleware/chain.rb +113 -56
- data/lib/sidekiq/middleware/current_attributes.rb +95 -0
- data/lib/sidekiq/middleware/i18n.rb +7 -7
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +146 -0
- data/lib/sidekiq/paginator.rb +28 -16
- data/lib/sidekiq/processor.rb +159 -107
- data/lib/sidekiq/rails.rb +54 -43
- data/lib/sidekiq/redis_client_adapter.rb +96 -0
- data/lib/sidekiq/redis_connection.rb +39 -81
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +139 -48
- data/lib/sidekiq/sd_notify.rb +149 -0
- data/lib/sidekiq/systemd.rb +24 -0
- data/lib/sidekiq/testing/inline.rb +6 -5
- data/lib/sidekiq/testing.rb +70 -88
- data/lib/sidekiq/transaction_aware_client.rb +44 -0
- data/lib/sidekiq/version.rb +3 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +143 -77
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +144 -106
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +60 -111
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +94 -183
- data/sidekiq.gemspec +25 -23
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +130 -61
- data/web/assets/javascripts/base-charts.js +106 -0
- data/web/assets/javascripts/chart.min.js +13 -0
- data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
- data/web/assets/javascripts/dashboard-charts.js +166 -0
- data/web/assets/javascripts/dashboard.js +36 -282
- data/web/assets/javascripts/metrics.js +264 -0
- data/web/assets/stylesheets/application-dark.css +147 -0
- data/web/assets/stylesheets/application-rtl.css +2 -95
- data/web/assets/stylesheets/application.css +134 -521
- data/web/assets/stylesheets/bootstrap.css +2 -2
- data/web/locales/ar.yml +71 -64
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +60 -53
- data/web/locales/de.yml +65 -53
- data/web/locales/el.yml +43 -24
- data/web/locales/en.yml +84 -65
- data/web/locales/es.yml +70 -54
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +83 -62
- data/web/locales/gd.yml +99 -0
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +53 -53
- data/web/locales/ja.yml +75 -64
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +83 -0
- data/web/locales/nb.yml +61 -61
- data/web/locales/nl.yml +52 -52
- data/web/locales/pl.yml +45 -45
- data/web/locales/pt-br.yml +63 -55
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +68 -63
- data/web/locales/sv.yml +53 -53
- data/web/locales/ta.yml +60 -60
- data/web/locales/uk.yml +62 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +83 -0
- data/web/locales/zh-cn.yml +43 -16
- data/web/locales/zh-tw.yml +42 -8
- data/web/views/_footer.erb +8 -2
- data/web/views/_job_info.erb +21 -4
- data/web/views/_metrics_period_select.erb +12 -0
- data/web/views/_nav.erb +4 -18
- data/web/views/_paging.erb +2 -0
- data/web/views/_poll_link.erb +3 -6
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +75 -25
- data/web/views/dashboard.erb +58 -18
- data/web/views/dead.erb +3 -3
- data/web/views/layout.erb +4 -2
- data/web/views/metrics.erb +82 -0
- data/web/views/metrics_for_job.erb +68 -0
- data/web/views/morgue.erb +14 -15
- data/web/views/queue.erb +33 -23
- data/web/views/queues.erb +14 -4
- data/web/views/retries.erb +19 -16
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +17 -15
- metadata +71 -140
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -13
- data/.travis.yml +0 -14
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/COMM-LICENSE +0 -95
- data/Ent-Changes.md +0 -210
- data/Gemfile +0 -8
- data/LICENSE +0 -9
- data/Pro-2.0-Upgrade.md +0 -138
- data/Pro-3.0-Upgrade.md +0 -44
- data/Pro-4.0-Upgrade.md +0 -35
- data/Pro-Changes.md +0 -716
- data/Rakefile +0 -8
- data/bin/sidekiqctl +0 -99
- data/code_of_conduct.md +0 -50
- data/lib/generators/sidekiq/worker_generator.rb +0 -49
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/delay.rb +0 -41
- data/lib/sidekiq/exception_handler.rb +0 -29
- data/lib/sidekiq/extensions/action_mailer.rb +0 -57
- data/lib/sidekiq/extensions/active_record.rb +0 -40
- data/lib/sidekiq/extensions/class_methods.rb +0 -40
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -22
- data/lib/sidekiq/middleware/server/active_record_cache.rb +0 -11
- data/lib/sidekiq/util.rb +0 -66
- data/lib/sidekiq/worker.rb +0 -204
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
|
data/lib/sidekiq/core_ext.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
raise "no longer used, will be removed in 5.1"
|
data/lib/sidekiq/delay.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Sidekiq
|
2
|
-
module Extensions
|
3
|
-
|
4
|
-
def self.enable_delay!
|
5
|
-
if defined?(::ActiveSupport)
|
6
|
-
require 'sidekiq/extensions/active_record'
|
7
|
-
require 'sidekiq/extensions/action_mailer'
|
8
|
-
|
9
|
-
# Need to patch Psych so it can autoload classes whose names are serialized
|
10
|
-
# in the delayed YAML.
|
11
|
-
Psych::Visitors::ToRuby.prepend(Sidekiq::Extensions::PsychAutoload)
|
12
|
-
|
13
|
-
ActiveSupport.on_load(:active_record) do
|
14
|
-
include Sidekiq::Extensions::ActiveRecord
|
15
|
-
end
|
16
|
-
ActiveSupport.on_load(:action_mailer) do
|
17
|
-
extend Sidekiq::Extensions::ActionMailer
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
require 'sidekiq/extensions/class_methods'
|
22
|
-
Module.__send__(:include, Sidekiq::Extensions::Klass)
|
23
|
-
end
|
24
|
-
|
25
|
-
module PsychAutoload
|
26
|
-
def resolve_class(klass_name)
|
27
|
-
return nil if !klass_name || klass_name.empty?
|
28
|
-
# constantize
|
29
|
-
names = klass_name.split('::')
|
30
|
-
names.shift if names.empty? || names.first.empty?
|
31
|
-
|
32
|
-
names.inject(Object) do |constant, name|
|
33
|
-
constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
34
|
-
end
|
35
|
-
rescue NameError
|
36
|
-
super
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'sidekiq'
|
3
|
-
|
4
|
-
module Sidekiq
|
5
|
-
module ExceptionHandler
|
6
|
-
|
7
|
-
class Logger
|
8
|
-
def call(ex, ctxHash)
|
9
|
-
Sidekiq.logger.warn(Sidekiq.dump_json(ctxHash)) if !ctxHash.empty?
|
10
|
-
Sidekiq.logger.warn("#{ex.class.name}: #{ex.message}")
|
11
|
-
Sidekiq.logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
|
12
|
-
end
|
13
|
-
|
14
|
-
Sidekiq.error_handlers << Sidekiq::ExceptionHandler::Logger.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def handle_exception(ex, ctxHash={})
|
18
|
-
Sidekiq.error_handlers.each do |handler|
|
19
|
-
begin
|
20
|
-
handler.call(ex, ctxHash)
|
21
|
-
rescue => ex
|
22
|
-
Sidekiq.logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
|
23
|
-
Sidekiq.logger.error ex
|
24
|
-
Sidekiq.logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'sidekiq/extensions/generic_proxy'
|
3
|
-
|
4
|
-
module Sidekiq
|
5
|
-
module Extensions
|
6
|
-
##
|
7
|
-
# Adds 'delay', 'delay_for' and `delay_until` methods to ActionMailer to offload arbitrary email
|
8
|
-
# delivery to Sidekiq. Example:
|
9
|
-
#
|
10
|
-
# UserMailer.delay.send_welcome_email(new_user)
|
11
|
-
# UserMailer.delay_for(5.days).send_welcome_email(new_user)
|
12
|
-
# UserMailer.delay_until(5.days.from_now).send_welcome_email(new_user)
|
13
|
-
class DelayedMailer
|
14
|
-
include Sidekiq::Worker
|
15
|
-
|
16
|
-
def perform(yml)
|
17
|
-
(target, method_name, args) = YAML.load(yml)
|
18
|
-
msg = target.public_send(method_name, *args)
|
19
|
-
# The email method can return nil, which causes ActionMailer to return
|
20
|
-
# an undeliverable empty message.
|
21
|
-
if msg
|
22
|
-
deliver(msg)
|
23
|
-
else
|
24
|
-
raise "#{target.name}##{method_name} returned an undeliverable mail object"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def deliver(msg)
|
31
|
-
if msg.respond_to?(:deliver_now)
|
32
|
-
# Rails 4.2/5.0
|
33
|
-
msg.deliver_now
|
34
|
-
else
|
35
|
-
# Rails 3.2/4.0/4.1
|
36
|
-
msg.deliver
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
module ActionMailer
|
42
|
-
def sidekiq_delay(options={})
|
43
|
-
Proxy.new(DelayedMailer, self, options)
|
44
|
-
end
|
45
|
-
def sidekiq_delay_for(interval, options={})
|
46
|
-
Proxy.new(DelayedMailer, self, options.merge('at' => Time.now.to_f + interval.to_f))
|
47
|
-
end
|
48
|
-
def sidekiq_delay_until(timestamp, options={})
|
49
|
-
Proxy.new(DelayedMailer, self, options.merge('at' => timestamp.to_f))
|
50
|
-
end
|
51
|
-
alias_method :delay, :sidekiq_delay
|
52
|
-
alias_method :delay_for, :sidekiq_delay_for
|
53
|
-
alias_method :delay_until, :sidekiq_delay_until
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'sidekiq/extensions/generic_proxy'
|
3
|
-
|
4
|
-
module Sidekiq
|
5
|
-
module Extensions
|
6
|
-
##
|
7
|
-
# Adds 'delay', 'delay_for' and `delay_until` methods to ActiveRecord to offload instance method
|
8
|
-
# execution to Sidekiq. Examples:
|
9
|
-
#
|
10
|
-
# User.recent_signups.each { |user| user.delay.mark_as_awesome }
|
11
|
-
#
|
12
|
-
# Please note, this is not recommended as this will serialize the entire
|
13
|
-
# object to Redis. Your Sidekiq jobs should pass IDs, not entire instances.
|
14
|
-
# This is here for backwards compatibility with Delayed::Job only.
|
15
|
-
class DelayedModel
|
16
|
-
include Sidekiq::Worker
|
17
|
-
|
18
|
-
def perform(yml)
|
19
|
-
(target, method_name, args) = YAML.load(yml)
|
20
|
-
target.__send__(method_name, *args)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module ActiveRecord
|
25
|
-
def sidekiq_delay(options={})
|
26
|
-
Proxy.new(DelayedModel, self, options)
|
27
|
-
end
|
28
|
-
def sidekiq_delay_for(interval, options={})
|
29
|
-
Proxy.new(DelayedModel, self, options.merge('at' => Time.now.to_f + interval.to_f))
|
30
|
-
end
|
31
|
-
def sidekiq_delay_until(timestamp, options={})
|
32
|
-
Proxy.new(DelayedModel, self, options.merge('at' => timestamp.to_f))
|
33
|
-
end
|
34
|
-
alias_method :delay, :sidekiq_delay
|
35
|
-
alias_method :delay_for, :sidekiq_delay_for
|
36
|
-
alias_method :delay_until, :sidekiq_delay_until
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'sidekiq/extensions/generic_proxy'
|
3
|
-
|
4
|
-
module Sidekiq
|
5
|
-
module Extensions
|
6
|
-
##
|
7
|
-
# Adds 'delay', 'delay_for' and `delay_until` methods to all Classes to offload class method
|
8
|
-
# execution to Sidekiq. Examples:
|
9
|
-
#
|
10
|
-
# User.delay.delete_inactive
|
11
|
-
# Wikipedia.delay.download_changes_for(Date.today)
|
12
|
-
#
|
13
|
-
class DelayedClass
|
14
|
-
include Sidekiq::Worker
|
15
|
-
|
16
|
-
def perform(yml)
|
17
|
-
(target, method_name, args) = YAML.load(yml)
|
18
|
-
target.__send__(method_name, *args)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module Klass
|
23
|
-
def sidekiq_delay(options={})
|
24
|
-
Proxy.new(DelayedClass, self, options)
|
25
|
-
end
|
26
|
-
def sidekiq_delay_for(interval, options={})
|
27
|
-
Proxy.new(DelayedClass, self, options.merge('at' => Time.now.to_f + interval.to_f))
|
28
|
-
end
|
29
|
-
def sidekiq_delay_until(timestamp, options={})
|
30
|
-
Proxy.new(DelayedClass, self, options.merge('at' => timestamp.to_f))
|
31
|
-
end
|
32
|
-
alias_method :delay, :sidekiq_delay
|
33
|
-
alias_method :delay_for, :sidekiq_delay_for
|
34
|
-
alias_method :delay_until, :sidekiq_delay_until
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
Module.__send__(:include, Sidekiq::Extensions::Klass) unless defined?(::Rails)
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
module Sidekiq
|
5
|
-
module Extensions
|
6
|
-
SIZE_LIMIT = 8_192
|
7
|
-
|
8
|
-
class Proxy < BasicObject
|
9
|
-
def initialize(performable, target, options={})
|
10
|
-
@performable = performable
|
11
|
-
@target = target
|
12
|
-
@opts = options
|
13
|
-
end
|
14
|
-
|
15
|
-
def method_missing(name, *args)
|
16
|
-
# Sidekiq has a limitation in that its message must be JSON.
|
17
|
-
# JSON can't round trip real Ruby objects so we use YAML to
|
18
|
-
# serialize the objects to a String. The YAML will be converted
|
19
|
-
# to JSON and then deserialized on the other side back into a
|
20
|
-
# Ruby object.
|
21
|
-
obj = [@target, name, args]
|
22
|
-
marshalled = ::YAML.dump(obj)
|
23
|
-
if marshalled.size > SIZE_LIMIT
|
24
|
-
::Sidekiq.logger.warn { "#{@target}.#{name} job argument is #{marshalled.bytesize} bytes, you should refactor it to reduce the size" }
|
25
|
-
end
|
26
|
-
@performable.client_push({ 'class' => @performable, 'args' => [marshalled] }.merge(@opts))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
data/lib/sidekiq/logging.rb
DELETED
@@ -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'.freeze] || job_hash["class".freeze]
|
37
|
-
bid = job_hash['bid'.freeze]
|
38
|
-
"#{klass} JID-#{job_hash['jid'.freeze]}#{" 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,22 +0,0 @@
|
|
1
|
-
module Sidekiq
|
2
|
-
module Middleware
|
3
|
-
module Server
|
4
|
-
class ActiveRecord
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
# With Rails 5+ we must use the Reloader **always**.
|
8
|
-
# The reloader handles code loading and db connection management.
|
9
|
-
if ::Rails::VERSION::MAJOR >= 5
|
10
|
-
raise ArgumentError, "Rails 5 no longer needs or uses the ActiveRecord middleware."
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(*args)
|
15
|
-
yield
|
16
|
-
ensure
|
17
|
-
::ActiveRecord::Base.clear_active_connections!
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/sidekiq/util.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'socket'
|
3
|
-
require 'securerandom'
|
4
|
-
require 'sidekiq/exception_handler'
|
5
|
-
|
6
|
-
module Sidekiq
|
7
|
-
##
|
8
|
-
# This module is part of Sidekiq core and not intended for extensions.
|
9
|
-
#
|
10
|
-
module Util
|
11
|
-
include ExceptionHandler
|
12
|
-
|
13
|
-
EXPIRY = 60 * 60 * 24
|
14
|
-
|
15
|
-
def watchdog(last_words)
|
16
|
-
yield
|
17
|
-
rescue Exception => ex
|
18
|
-
handle_exception(ex, { context: last_words })
|
19
|
-
raise ex
|
20
|
-
end
|
21
|
-
|
22
|
-
def safe_thread(name, &block)
|
23
|
-
Thread.new do
|
24
|
-
Thread.current['sidekiq_label'.freeze] = name
|
25
|
-
watchdog(name, &block)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def logger
|
30
|
-
Sidekiq.logger
|
31
|
-
end
|
32
|
-
|
33
|
-
def redis(&block)
|
34
|
-
Sidekiq.redis(&block)
|
35
|
-
end
|
36
|
-
|
37
|
-
def hostname
|
38
|
-
ENV['DYNO'] || Socket.gethostname
|
39
|
-
end
|
40
|
-
|
41
|
-
def process_nonce
|
42
|
-
@@process_nonce ||= SecureRandom.hex(6)
|
43
|
-
end
|
44
|
-
|
45
|
-
def identity
|
46
|
-
@@identity ||= "#{hostname}:#{$$}:#{process_nonce}"
|
47
|
-
end
|
48
|
-
|
49
|
-
def fire_event(event, options={})
|
50
|
-
reverse = options[:reverse]
|
51
|
-
reraise = options[:reraise]
|
52
|
-
|
53
|
-
arr = Sidekiq.options[:lifecycle_events][event]
|
54
|
-
arr.reverse! if reverse
|
55
|
-
arr.each do |block|
|
56
|
-
begin
|
57
|
-
block.call
|
58
|
-
rescue => ex
|
59
|
-
handle_exception(ex, { context: "Exception during Sidekiq lifecycle event.", event: event })
|
60
|
-
raise ex if reraise
|
61
|
-
end
|
62
|
-
end
|
63
|
-
arr.clear
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|