Last active
June 18, 2016 15:06
-
-
Save barockok/0e622824bf1d90aa87d78cc8b307f46b to your computer and use it in GitHub Desktop.
common function to scripting daemon process
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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