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