Skip to content

Commit

Permalink
Allow disabling of cron polling (#368)
Browse files Browse the repository at this point in the history
When running with very many Sidekiq processes, polling on each one of
them can be expensive and unnecessary too.

This allows disabling polling by setting `cron_poll_interval` to zero.
  • Loading branch information
engwan authored Sep 23, 2022
1 parent 704d436 commit 01f46f9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ Sidekiq[:cron_poll_interval] = 10

Sidekiq-Cron is safe to use with multiple Sidekiq processes or nodes. It uses a Redis sorted set to determine that only the first process who asks can enqueue scheduled jobs into the queue.

When running with many Sidekiq processes, the polling can add significant load to Redis. You can disable polling on some processes by setting `Sidekiq[:cron_poll_interval] = 0` on these processes.

## Contributing

**Thanks to all [contributors](https://github.com/ondrejbartas/sidekiq-cron/graphs/contributors), you’re awesome and this wouldn’t be possible without you!**
Expand Down
12 changes: 8 additions & 4 deletions lib/sidekiq/cron/launcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,34 @@
module Sidekiq
module Cron
module Launcher
DEFAULT_POLL_INTERVAL = 30

# Add cron poller to launcher.
attr_reader :cron_poller

# Add cron poller and execute normal initialize of Sidekiq launcher.
def initialize(options)
@cron_poller = Sidekiq::Cron::Poller.new(options)
options[:cron_poll_interval] = DEFAULT_POLL_INTERVAL if options[:cron_poll_interval].nil?

@cron_poller = Sidekiq::Cron::Poller.new(options) if options[:cron_poll_interval] > 0
super(options)
end

# Execute normal run of launcher and run cron poller.
def run
super
cron_poller.start
cron_poller.start if @cron_poller
end

# Execute normal quiet of launcher and quiet cron poller.
def quiet
cron_poller.terminate
cron_poller.terminate if @cron_poller
super
end

# Execute normal stop of launcher and stop cron poller.
def stop
cron_poller.terminate
cron_poller.terminate if @cron_poller
super
end
end
Expand Down
4 changes: 1 addition & 3 deletions lib/sidekiq/cron/poller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

module Sidekiq
module Cron
POLL_INTERVAL = 30

# The Poller checks Redis every N seconds for sheduled cron jobs.
class Poller < Sidekiq::Scheduled::Poller
def initialize(options = {})
Expand Down Expand Up @@ -44,7 +42,7 @@ def enqueue_job(job, time = Time.now.utc)
end

def poll_interval_average(process_count = 1)
@config[:cron_poll_interval] || POLL_INTERVAL
@config[:cron_poll_interval]
end
end
end
Expand Down
33 changes: 33 additions & 0 deletions test/unit/launcher_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require './test/test_helper'

describe 'Cron launcher' do
describe 'initialization' do
before do
Sidekiq[:cron_poll_interval] = nil
end

it 'initializes poller with default poll interval when not configured' do
Sidekiq::Cron::Poller.expects(:new).with do |options|
assert_equal Sidekiq::Cron::Launcher::DEFAULT_POLL_INTERVAL, options[:cron_poll_interval]
end

Sidekiq::Launcher.new(Sidekiq)
end

it 'initializes poller with the configured poll interval' do
Sidekiq::Cron::Poller.expects(:new).with do |options|
assert_equal 99, options[:cron_poll_interval]
end

Sidekiq[:cron_poll_interval] = 99
Sidekiq::Launcher.new(Sidekiq)
end

it 'does not initialize the poller when interval is 0' do
Sidekiq::Cron::Poller.expects(:new).never

Sidekiq[:cron_poll_interval] = 0
Sidekiq::Launcher.new(Sidekiq)
end
end
end

0 comments on commit 01f46f9

Please sign in to comment.