mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
make the average global poller delay configurable
This commit is contained in:
parent
1825f28058
commit
4255aaf0c2
3 changed files with 61 additions and 9 deletions
|
@ -20,6 +20,8 @@ module Sidekiq
|
||||||
require: '.',
|
require: '.',
|
||||||
environment: nil,
|
environment: nil,
|
||||||
timeout: 8,
|
timeout: 8,
|
||||||
|
poll_interval_average: nil,
|
||||||
|
global_poll_interval_average: 15,
|
||||||
error_handlers: [],
|
error_handlers: [],
|
||||||
lifecycle_events: {
|
lifecycle_events: {
|
||||||
startup: [],
|
startup: [],
|
||||||
|
@ -127,9 +129,13 @@ module Sidekiq
|
||||||
Sidekiq::Logging.logger = log
|
Sidekiq::Logging.logger = log
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# When set, overrides Sidekiq.options[:global_poll_interval_average] and sets the
|
||||||
|
# average interval that this process will delay before checking for scheduled jobs
|
||||||
|
# or job retries that are ready to run.
|
||||||
|
#
|
||||||
# See sidekiq/scheduled.rb for an in-depth explanation of this value
|
# See sidekiq/scheduled.rb for an in-depth explanation of this value
|
||||||
def self.poll_interval=(interval)
|
def self.poll_interval=(interval)
|
||||||
self.options[:poll_interval] = interval
|
self.options[:poll_interval_average] = interval
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register a proc to handle any error which occurs within the Sidekiq process.
|
# Register a proc to handle any error which occurs within the Sidekiq process.
|
||||||
|
|
|
@ -68,7 +68,7 @@ module Sidekiq
|
||||||
|
|
||||||
# Calculates a random interval that is ±50% the desired average.
|
# Calculates a random interval that is ±50% the desired average.
|
||||||
def random_poll_interval
|
def random_poll_interval
|
||||||
poll_interval * rand + poll_interval.to_f / 2
|
poll_interval_average * rand + poll_interval_average.to_f / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
# We do our best to tune poll_interval to the size of the active Sidekiq
|
# We do our best to tune poll_interval to the size of the active Sidekiq
|
||||||
|
@ -84,13 +84,17 @@ module Sidekiq
|
||||||
# the same time: the thundering herd problem.
|
# the same time: the thundering herd problem.
|
||||||
#
|
#
|
||||||
# We only do this if poll_interval is unset (the default).
|
# We only do this if poll_interval is unset (the default).
|
||||||
def poll_interval
|
def poll_interval_average
|
||||||
Sidekiq.options[:poll_interval] ||= begin
|
Sidekiq.options[:poll_interval_average] ||= scaled_poll_interval
|
||||||
ps = Sidekiq::ProcessSet.new
|
end
|
||||||
pcount = ps.size
|
|
||||||
pcount = 1 if pcount == 0
|
# Calculates an average poll interval based on the number of known Sidekiq processes.
|
||||||
pcount * 15
|
# This minimizes a single point of failure by dispersing check-ins but without taxing
|
||||||
end
|
# Redis if you run many Sidekiq processes.
|
||||||
|
def scaled_poll_interval
|
||||||
|
pcount = Sidekiq::ProcessSet.new.size
|
||||||
|
pcount = 1 if pcount == 0
|
||||||
|
pcount * Sidekiq.options[:global_poll_interval_average]
|
||||||
end
|
end
|
||||||
|
|
||||||
def initial_wait
|
def initial_wait
|
||||||
|
|
|
@ -82,5 +82,47 @@ class TestScheduled < Sidekiq::Test
|
||||||
assert_equal 1, @scheduled.size
|
assert_equal 1, @scheduled.size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def with_sidekiq_option(name, value)
|
||||||
|
_original, Sidekiq.options[name] = Sidekiq.options[name], value
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
Sidekiq.options[name] = _original
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'generates random intervals that target a configured average' do
|
||||||
|
with_sidekiq_option(:poll_interval_average, 10) do
|
||||||
|
i = 500
|
||||||
|
intervals = i.times.map{ @poller.send(:random_poll_interval) }
|
||||||
|
|
||||||
|
assert intervals.all?{|i| i >= 5}
|
||||||
|
assert intervals.all?{|i| i <= 15}
|
||||||
|
assert_in_delta 10, intervals.reduce(&:+).to_f / i, 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'calculates an average poll interval based on the number of known Sidekiq processes' do
|
||||||
|
with_sidekiq_option(:global_poll_interval_average, 10) do
|
||||||
|
begin
|
||||||
|
3.times do |i|
|
||||||
|
Sidekiq.redis do |conn|
|
||||||
|
conn.sadd("processes", "process-#{i}")
|
||||||
|
conn.hset("process-#{i}", "info", nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 30, @poller.send(:scaled_poll_interval)
|
||||||
|
ensure
|
||||||
|
3.times do |i|
|
||||||
|
Sidekiq.redis do |conn|
|
||||||
|
conn.srem("processes", "process-#{i}")
|
||||||
|
conn.del("process-#{i}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue