module NdrDevSupport::Daemon::Stoppable
Behaviour that allows daemons to be restarted, and stopped by god. To use, you need to call ‘super` in the initialize method, if defined.
Constants
- BIG_SLEEP
how long the daemon waits when it runs out of things to do:
- LITTLE_SLEEP
when idle, how long the daemon between making restart checks?
- MAX_MEMORY
- MAX_UPTIME
- RESTART_FILENAME
touch this file to trigger graceful exit
Attributes
logger[W]
name[R]
start_time[R]
Public Class Methods
new(*)
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 29 def initialize(*) setup_signals @start_time = Time.current end
Public Instance Methods
log(message, level = :info)
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 70 def log(message, level = :info) tags = "[#{Time.current.to_formatted_s(:db)}] [#{level.upcase}] " \ "[daemon: #{name} (#{Process.pid})]" message = "#{tags} #{message}" logger.send(level, message) end
logger()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 66 def logger @logger ||= defined?(Rails) && Rails.logger ? Rails.logger : Logger.new($stdout) end
run(exit_when_done: false)
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 43 def run(exit_when_done: false) loop do run_once # we've done all we can for the time being; either exit now, or # have a sleep and loop round for another go: break if exit_when_done snooze(BIG_SLEEP) # Our snooze may have come to an abrupt end: break if should_stop? end if should_stop? # An instruction to stop has been received: log('Stopping') return :stopped else # Processing has come to a natural end: log('Done, exiting') return :exiting end end
should_stop?()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 39 def should_stop? @should_stop ||= restart_file_touched? || excessive_memory? || been_up_a_while? end
stop()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 35 def stop @should_stop = true end
Private Instance Methods
been_up_a_while?()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 94 def been_up_a_while? start_time < MAX_UPTIME.ago end
excessive_memory?()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 88 def excessive_memory? (`ps -o rss= -p #{$$}`.to_i.kilobytes) > MAX_MEMORY rescue false end
restart_file_touched?()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 84 def restart_file_touched? File.exist?(RESTART_FILENAME) && File.mtime(RESTART_FILENAME) > start_time end
setup_signals()
click to toggle source
# File lib/ndr_dev_support/daemon/stoppable.rb, line 80 def setup_signals Signal.trap('TERM') { stop } end
snooze(duration)
click to toggle source
sleeps for ‘duration`, but wakes up periodically to see if the daemon has been asked to restart. If so, returns immediately.
# File lib/ndr_dev_support/daemon/stoppable.rb, line 101 def snooze(duration) number_of_mini_sleeps = duration / LITTLE_SLEEP initial_sleep_length = duration % LITTLE_SLEEP sleep(initial_sleep_length) number_of_mini_sleeps.times do return if should_stop? sleep(LITTLE_SLEEP) rescue Interrupt # Ctrl-C should stop cleanly if used while the process is snoozing @should_stop = true return end end