lib/clockwork/manager.rb in clockwork-2.0.0 vs lib/clockwork/manager.rb in clockwork-2.0.1

- old
+ new

@@ -7,10 +7,13 @@ def initialize @events = [] @callbacks = {} @config = default_configuration @handler = nil + @mutex = Mutex.new + @condvar = ConditionVariable.new + @finish = false end def thread_available? Thread.list.select { |t| t['creator'] == self }.count < config[:max_threads] end @@ -58,17 +61,75 @@ @callbacks[event].nil? || @callbacks[event].all? { |h| h.call(*args) } end def run log "Starting clock for #{@events.size} events: [ #{@events.map(&:to_s).join(' ')} ]" - loop do - tick - interval = config[:sleep_timeout] - Time.now.subsec + 0.001 - sleep(interval) if interval > 0 + + sig_read, sig_write = IO.pipe + + %w[INT TERM HUP].each do |sig| + trap sig do + sig_write.puts(sig) + end end + + run_tick_loop + + while io = IO.select([sig_read]) + sig = io.first[0].gets.chomp + handle_signal(sig) + end end + def handle_signal(sig) + logger.debug "Got #{sig} signal" + case sig + when 'INT' + shutdown + when 'TERM' + # Heroku sends TERM signal, and waits 10 seconds before exit + graceful_shutdown + when 'HUP' + graceful_shutdown + end + end + + def shutdown + logger.info 'Shutting down' + stop_tick_loop + exit(0) + end + + def graceful_shutdown + logger.info 'Gracefully shutting down' + stop_tick_loop + wait_tick_loop_finishes + exit(0) + end + + def stop_tick_loop + @finish = true + end + + def wait_tick_loop_finishes + @mutex.synchronize do # wait by synchronize + @condvar.signal + end + end + + def run_tick_loop + Thread.new do + @mutex.synchronize do + until @finish + tick + interval = config[:sleep_timeout] - Time.now.subsec + 0.001 + @condvar.wait(@mutex, interval) if interval > 0 + end + end + end + end + def tick(t=Time.now) if (fire_callbacks(:before_tick)) events = events_to_run(t) events.each do |event| if (fire_callbacks(:before_run, event, t)) @@ -77,9 +138,13 @@ end end end fire_callbacks(:after_tick) events + end + + def logger + config[:logger] end def log_error(e) config[:logger].error(e) end