Skip to content

Instantly share code, notes, and snippets.

@barockok
Last active June 18, 2016 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barockok/0e622824bf1d90aa87d78cc8b307f46b to your computer and use it in GitHub Desktop.
Save barockok/0e622824bf1d90aa87d78cc8b307f46b to your computer and use it in GitHub Desktop.
common function to scripting daemon process
require 'socket'
require 'set'
require 'securerandom'
module Helper
module ProcessCLI
def running_daemon command
puts "RUNNING : #{command}"
pid_file = "/tmp/ruby-processcli-#{SecureRandom.uuid}.pid"
if ENV['SHOW_BG_OUTPUT']
system("#{command} & echo $! > #{pid_file}")
else
system("#{command} > /dev/null & echo $! > #{pid_file}")
end
File.read(pid_file).strip.to_i
end
def check_socket_live host, port, attempt=10, initial=true
s = TCPSocket.new host, port
s.close
print "\n"
rescue Errno::ECONNREFUSED
if initial
print "-> check socket on #{host}:#{port} "
else
print "."
end
if attempt > 0
sleep 1
check_socket_live host, port, attempt-1, false
else
raise
end
end
def process_exist?(pidfile)
pid = get_pid(pidfile)
Process.getpgid( pid )
return true
rescue Errno::ESRCH
false
end
def get_pid(pidfile_or_pid)
if pidfile_or_pid.is_a?(String)
File.read(pidfile_or_pid).to_i
else
pidfile_or_pid
end
end
def kill_process(pidfile, attempt=10, initial=true)
pid = get_pid(pidfile)
if initial
print "kill process pid:#{pid} "
else
print "."
end
if attempt > 0
# soft kill
Process.kill(0, pid)
system("kill #{pid}")
else
# force kill
system("kill -9 #{pid}")
print "\n"
return true
end
sleep 1
if process_exist?(pid)
kill_process(pid, attempt-1, false)
else
print "\n"
return true
end
rescue Errno::ESRCH
return true
end
def trap_signal writter
%w(INT TERM USR1 USR2 TTIN).each do |sig|
begin
trap sig do
writter.puts(sig)
end
rescue ArgumentError
puts "Signal #{sig} not supported"
end
end
end
def watch_read_io reader
while readable_io = IO.select([reader])
signal = readable_io.first[0].gets.strip
signal_handler(signal)
end
end
def run!
self_read, self_write = IO.pipe
trap_signal self_write
begin
start_service
watch_read_io self_read
rescue Exception => e
raise unless $stop_exceptions.include?(e.class)
puts "EXITING : #{e.message}"
stop_service
exit(0)
end
end
def add_stop_exception *exceptions
$stop_exceptions += Set.new(exceptions)
end
def self.included base
$stdout.sync = true
$stop_exceptions = Set.new
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment