diff --git a/lib/sidekiq.rb b/lib/sidekiq.rb index 6764fd1d..ec971606 100644 --- a/lib/sidekiq.rb +++ b/lib/sidekiq.rb @@ -28,6 +28,7 @@ module Sidekiq startup: [], quiet: [], shutdown: [], + heartbeat: [], }, dead_max_jobs: 10_000, dead_timeout_in_seconds: 180 * 24 * 60 * 60 # 6 months diff --git a/lib/sidekiq/launcher.rb b/lib/sidekiq/launcher.rb index d30ffd47..46154a37 100644 --- a/lib/sidekiq/launcher.rb +++ b/lib/sidekiq/launcher.rb @@ -94,15 +94,19 @@ module Sidekiq end fails = procd = 0 - _, _, _, msg = Sidekiq.redis do |conn| + _, exists, _, _, msg = Sidekiq.redis do |conn| conn.multi do conn.sadd('processes', key) + conn.exists(key) conn.hmset(key, 'info', json, 'busy', Processor::WORKER_STATE.size, 'beat', Time.now.to_f, 'quiet', @done) conn.expire(key, 60) conn.rpop("#{key}-signals") end end + # first heartbeat or recovering from an outage and need to reestablish our heartbeat + fire_event(:heartbeat) if !exists + return unless msg if JVM_RESERVED_SIGNALS.include?(msg) diff --git a/test/test_launcher.rb b/test/test_launcher.rb index bd86bd21..72f3270a 100644 --- a/test/test_launcher.rb +++ b/test/test_launcher.rb @@ -15,8 +15,6 @@ class TestLauncher < Sidekiq::Test describe 'heartbeat' do before do - uow = Object.new - @mgr = new_manager(options) @launcher = Sidekiq::Launcher.new(options) @launcher.manager = @mgr @@ -31,6 +29,18 @@ class TestLauncher < Sidekiq::Test $0 = @proctitle end + it 'fires new heartbeat events' do + i = 0 + Sidekiq.on(:heartbeat) do + i += 1 + end + assert_equal 0, i + @launcher.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data)) + assert_equal 1, i + @launcher.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data)) + assert_equal 1, i + end + describe 'when manager is active' do before do Sidekiq::CLI::PROCTITLES << proc { "xyz" }