1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00
mperham--sidekiq/bin/sidekiqload

162 lines
4 KiB
Text
Raw Normal View History

2015-10-01 16:37:58 -07:00
#!/usr/bin/env ruby
# Quiet some warnings we see when running in warning mode:
# RUBYOPT=-w bundle exec sidekiq
$TESTING = false
2022-01-26 15:33:23 -08:00
# require "ruby-prof"
require "bundler/setup"
2019-09-10 14:06:26 +03:00
Bundler.require(:default, :load_test)
2022-01-26 15:33:23 -08:00
require_relative "../lib/sidekiq/cli"
require_relative "../lib/sidekiq/launcher"
2015-10-01 16:37:58 -07:00
if ENV["SIDEKIQ_REDIS_CLIENT"]
Sidekiq::RedisConnection.adapter = :redis_client
end
2015-10-01 16:37:58 -07:00
Sidekiq.configure_server do |config|
config.options[:concurrency] = 10
2022-01-26 15:33:23 -08:00
config.redis = {db: 13, port: 6380}
# config.redis = { db: 13, port: 6380, driver: :hiredis}
config.options[:queues] << "default"
2015-10-01 16:37:58 -07:00
config.logger.level = Logger::ERROR
config.average_scheduled_poll_interval = 2
2015-11-12 14:00:04 -08:00
config.reliable! if defined?(Sidekiq::Pro)
2015-10-01 16:37:58 -07:00
end
class LoadWorker
include Sidekiq::Worker
sidekiq_options retry: 1
sidekiq_retry_in do |x|
1
end
2022-01-26 15:33:23 -08:00
def perform(idx, ts = nil)
puts(Time.now.to_f - ts) if !ts.nil?
# raise idx.to_s if idx % 100 == 1
2015-10-01 16:37:58 -07:00
end
end
2015-10-07 19:20:17 -07:00
# brew tap shopify/shopify
# brew install toxiproxy
# run `toxiproxy-server` in a separate terminal window.
2022-01-26 15:33:23 -08:00
require "toxiproxy"
2015-10-07 19:20:17 -07:00
# simulate a non-localhost network for realer-world conditions.
# adding 1ms of network latency has an ENORMOUS impact on benchmarks
Toxiproxy.populate([{
2022-01-26 15:33:23 -08:00
name: "redis",
listen: "127.0.0.1:6380",
upstream: "127.0.0.1:6379"
}])
2015-10-07 19:20:17 -07:00
2015-10-01 16:37:58 -07:00
self_read, self_write = IO.pipe
2022-01-26 15:33:23 -08:00
%w[INT TERM TSTP TTIN].each do |sig|
trap sig do
self_write.puts(sig)
2015-10-01 16:37:58 -07:00
end
2022-01-26 15:33:23 -08:00
rescue ArgumentError
puts "Signal #{sig} not supported"
2015-10-01 16:37:58 -07:00
end
2022-01-26 15:33:23 -08:00
Sidekiq.redis { |c| c.flushdb }
2015-10-01 16:37:58 -07:00
def handle_signal(launcher, sig)
Sidekiq.logger.debug "Got #{sig} signal"
case sig
2022-01-26 15:33:23 -08:00
when "INT"
2015-10-01 16:37:58 -07:00
# Handle Ctrl-C in JRuby like MRI
# http://jira.codehaus.org/browse/JRUBY-4637
raise Interrupt
2022-01-26 15:33:23 -08:00
when "TERM"
# Heroku sends TERM and then waits 30 seconds for process to exit.
2015-10-01 16:37:58 -07:00
raise Interrupt
2022-01-26 15:33:23 -08:00
when "TSTP"
2017-01-03 15:41:48 -08:00
Sidekiq.logger.info "Received TSTP, no longer accepting new work"
2015-10-06 14:51:06 -07:00
launcher.quiet
2022-01-26 15:33:23 -08:00
when "TTIN"
2015-10-01 16:37:58 -07:00
Thread.list.each do |thread|
2022-01-26 15:33:23 -08:00
Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread["label"]}"
2015-10-01 16:37:58 -07:00
if thread.backtrace
Sidekiq.logger.warn thread.backtrace.join("\n")
else
Sidekiq.logger.warn "<no backtrace available>"
end
end
end
end
def Process.rss
`ps -o rss= -p #{Process.pid}`.chomp.to_i
end
iter = 50
2015-10-01 16:37:58 -07:00
count = 10_000
iter.times do
arr = Array.new(count) { |idx| [idx] }
2022-01-26 15:33:23 -08:00
Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
2015-10-01 16:37:58 -07:00
end
2022-01-26 15:33:23 -08:00
Sidekiq.logger.error "Created #{count * iter} jobs"
2015-10-01 16:37:58 -07:00
2019-10-01 19:40:02 -07:00
start = Time.now
2015-10-01 16:37:58 -07:00
Monitoring = Thread.new do
2022-01-26 15:33:23 -08:00
while true
sleep 0.2
qsize = Sidekiq.redis do |conn|
conn.llen "queue:default"
end
total = qsize
# Sidekiq.logger.error("RSS: #{Process.rss} Pending: #{total}")
if total == 0
Sidekiq.logger.error("Done, #{iter * count} jobs in #{Time.now - start} sec")
Sidekiq.logger.error("Now here's the latency for three jobs")
LoadWorker.perform_async(1, Time.now.to_f)
LoadWorker.perform_async(2, Time.now.to_f)
LoadWorker.perform_async(3, Time.now.to_f)
2019-10-01 19:40:02 -07:00
sleep 0.2
2022-01-26 15:33:23 -08:00
exit(0)
2015-10-01 16:37:58 -07:00
end
2022-01-26 15:33:23 -08:00
end
2015-10-01 16:37:58 -07:00
end
def with_latency(latency, &block)
Sidekiq.logger.error "Simulating #{latency}ms of latency between Sidekiq and redis"
if latency > 0
Toxiproxy[:redis].downstream(:latency, latency: latency).apply(&block)
else
yield
end
end
2015-10-01 16:37:58 -07:00
begin
2022-01-26 15:33:23 -08:00
# RubyProf::exclude_threads = [ Monitoring ]
# RubyProf.start
events = Sidekiq.options[:lifecycle_events][:startup]
events.each(&:call)
events.clear
with_latency(Integer(ENV.fetch("LATENCY", "1"))) do
2015-10-07 16:56:10 -07:00
launcher = Sidekiq::Launcher.new(Sidekiq.options)
launcher.run
2015-10-01 16:37:58 -07:00
2015-10-07 16:56:10 -07:00
while readable_io = IO.select([self_read])
signal = readable_io.first[0].gets.strip
handle_signal(launcher, signal)
end
end
2015-10-01 16:37:58 -07:00
rescue SystemExit => e
2022-01-26 15:33:23 -08:00
# Sidekiq.logger.error("Profiling...")
# result = RubyProf.stop
# printer = RubyProf::GraphHtmlPrinter.new(result)
# printer.print(File.new("output.html", "w"), :min_percent => 1)
2015-10-01 16:37:58 -07:00
# normal
rescue => e
raise e if $DEBUG
2022-01-26 15:33:23 -08:00
warn e.message
warn e.backtrace.join("\n")
2015-10-01 16:37:58 -07:00
exit 1
end