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

Add logic to self-tune the poll_interval based on available

heartbeat info.

Fixes #1630
This commit is contained in:
Mike Perham 2014-06-07 15:12:31 -07:00
parent 3452efaf0b
commit eac17801bd
4 changed files with 33 additions and 10 deletions

View file

@ -1,3 +1,12 @@
3.1.4
-----------
- Happy π release!
- Self-tuning Scheduler polling, we use heartbeat info to better tune poll\_inteval [#1630]
- Remove all table column width rules, hopefully get better column formatting [#1747]
- Handle rare case where YAML can't be decoded in dev mode [#1761]
- Fix lingering jobs in Busy page on Heroku [#1764]
3.1.3
-----------

View file

@ -118,9 +118,7 @@ module Sidekiq
Sidekiq::Logging.logger = log
end
# The default poll interval is 15 seconds. This should generally be set to
# (Sidekiq process count * 5). So if you have a dozen Sidekiq processes, set
# poll_interval to 60.
# See sidekiq/scheduled.rb for an in-depth explanation of this value
def self.poll_interval=(interval)
self.options[:poll_interval] = interval
end

View file

@ -5,7 +5,7 @@ require 'sidekiq/actor'
module Sidekiq
module Scheduled
POLL_INTERVAL = 15
INITIAL_WAIT = 15
##
# The Poller checks Redis every N seconds for messages in the retry or scheduled
@ -20,7 +20,7 @@ module Sidekiq
def poll(first_time=false)
watchdog('scheduling poller thread died!') do
add_jitter if first_time
initial_wait if first_time
begin
# A message's "score" in Redis is the time at which it should be processed.
@ -51,19 +51,35 @@ module Sidekiq
logger.error ex.backtrace.first
end
after(poll_interval) { poll }
after(poll_interval * rand) { poll }
end
end
private
# We do our best to tune poll_interval to the size of the active Sidekiq
# cluster. If you have 30 processes and poll every 15 seconds, that means one
# Sidekiq is checking Redis every 0.5 seconds - way too often for most people
# and really bad if the retry or scheduled sets are large.
#
# Instead try to avoid polling more than once every 15 seconds. If you have
# 30 Sidekiq processes, we'll set poll_interval to 30 * 15 * 2 or 900 seconds.
# To keep things statistically random, we'll sleep a random amount between
# 0 and 900 seconds for each poll or 450 seconds on average. Otherwise restarting
# all your Sidekiq processes at the same time will lead to them all polling at
# the same time: the thundering herd problem.
#
# We only do this if poll_interval is unset (the default).
def poll_interval
Sidekiq.options[:poll_interval] || POLL_INTERVAL
Sidekiq.options[:poll_interval] ||= begin
pcount = Sidekiq.redis {|c| c.scard('processes') } || 1
pcount * 15 * 2
end
end
def add_jitter
def initial_wait
begin
sleep(poll_interval * rand)
sleep(INITIAL_WAIT)
rescue Celluloid::Task::TerminatedError
# Hit Ctrl-C when Sidekiq is finished booting and we have a chance
# to get here.

View file

@ -1,3 +1,3 @@
module Sidekiq
VERSION = "3.1.3"
VERSION = "3.1.4"
end