From 210e629a15c9dc0f84c8dbe3a7d7468cb9cb5469 Mon Sep 17 00:00:00 2001 From: Nathan Woodhull Date: Wed, 3 May 2017 16:14:02 -0400 Subject: [PATCH] add jitter to the time when retries are scheduled. this is helpful in our particular use case --- .../schedule_in_future_strategy.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/sidekiq-rate-limiter/schedule_in_future_strategy.rb b/lib/sidekiq-rate-limiter/schedule_in_future_strategy.rb index 7563c67..f0e65da 100644 --- a/lib/sidekiq-rate-limiter/schedule_in_future_strategy.rb +++ b/lib/sidekiq-rate-limiter/schedule_in_future_strategy.rb @@ -4,8 +4,16 @@ def call(work, klass, args, options) Sidekiq.redis do |conn| lim = Limit.new(conn, options) if lim.exceeded?(klass) + + # add a random amount of jitter that is proportional to the length of time the retry is in the future. + # this helps us spread out the jobs more evenly, as clumps of jobs on the queue can interfere with normal + # throughput of non-rate limited jobs. This jitter is additive. It's also useful in cases where we would like + # to dump thousands of jobs onto the queue and eventually have them delivered. + retry_in = lim.retry_in?(klass) + retry_in = retry_in + rand(retry_in/5) if retry_in > 10 + # Schedule the job to be executed in the future, when we think the rate limit might be back to normal. - Sidekiq::Client.enqueue_to_in(work.queue_name, lim.retry_in?(klass), Object.const_get(klass), *args) + Sidekiq::Client.enqueue_to_in(work.queue_name, retry_in, Object.const_get(klass), *args) nil else lim.add(klass)