Created
October 18, 2012 07:36
-
-
Save SpringMT/3910306 to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/env ruby | |
# encoding: UTF-8 | |
require 'ap' | |
require 'optparse' | |
class UnicornStarter | |
def initialize(rails_env, rails_home, timeout) | |
@rails_env = rails_env | |
@rails_home = rails_home | |
@pid_file = "#{rails_home}/tmp/pids/unicorn.pid" | |
@timeout = timeout | |
end | |
def usage | |
puts "----- default -----" | |
puts "timeout : #{@timeout}" | |
puts "RAILS_ENV : #{@rails_env}" | |
puts "rails home : #{@rails_home}" | |
puts "----- usage -----" | |
puts "#{$0} {start|stop|restart|status} [-e RAILS_ENV] [-h RAILS_HOME] [-t timeout_sec]" | |
end | |
def start | |
exit 0 if is_unicorn_running? | |
cmd = "bundle exec unicorn -p 3000 -c #{@rails_home}/config/unicorn.rb -D" | |
pid = spawn({'RAILS_ENV' => @rails_env}, cmd) | |
# 起動するまで待つ | |
Process.waitpid pid | |
if File.exists? @pid_file | |
new_pid = open(@pid_file).read.to_i | |
end | |
unless new_pid | |
puts 'Failure' | |
exit 1 | |
end | |
# 正常に起動できているか確認 | |
begin | |
res = Process.kill(0, new_pid) | |
rescue => e | |
ap e.message | |
puts 'Failure! Check ps aux | grep "unicorn"' | |
exit 1 | |
else | |
# killはシグナル送信に成功した場合、指定した pid の数返す | |
if res == 1 | |
puts 'Success' | |
exit 0 | |
else | |
puts 'Somethig wrong' | |
exit 1 | |
end | |
end | |
end | |
def stop | |
exit 0 if is_unicorn_stop? | |
pid = open(@pid_file).read.to_i | |
puts "stop pid: #{pid}" | |
Process.kill :QUIT, pid | |
timeout_count = 0 | |
# 正常に終了しているか確認 | |
loop do | |
exit 1 if is_timeout?(@timeout, timeout_count) | |
if File.exists? @pid_file | |
print '.' | |
STDOUT.flush | |
else | |
begin | |
res = Process.kill(0, pid) | |
rescue => e | |
# プロセスがなくなると、例外が発生する | |
if e.message == 'No such process' | |
puts 'Success' | |
exit 0 | |
end | |
end | |
end | |
sleep 1 | |
timeout_count += 1 | |
end | |
end | |
def restart | |
exit 0 if is_unicorn_stop? | |
exit 0 if is_unicorn_restarting? | |
old_pid = open(@pid_file).read.to_i | |
old_pid_file = "#{@pid_file}.oldbin" | |
puts "Send Signal USR2 to the pid: #{old_pid}" | |
Process.kill(:USR2, old_pid) | |
# 再起動が成功しているか確認 | |
timeout_count = 0 | |
new_pid = nil | |
loop do | |
exit 1 if is_timeout?(@timeout, timeout_count) | |
if new_pid | |
if File.exist?(old_pid_file) | |
print '.' | |
STDOUT.flush | |
else | |
if open(@pid_file).read.to_i == old_pid | |
puts 'Failure' | |
exit 1 | |
else | |
puts 'Success' | |
exit 0 | |
end | |
end | |
else | |
if File.exist? @pid_file | |
new_pid = open(@pid_file).read.to_i | |
end | |
end | |
sleep 1 | |
timeout_count += 1 | |
end | |
end | |
def status | |
old_pid_file = "#{@pid_file}.oldbin" | |
if File.exists? @pid_file | |
pid = open(@pid_file).read.to_i | |
if File.exists? old_pid_file | |
puts 'Restarting' | |
else | |
begin | |
res = Process.kill(0, pid) | |
rescue => e | |
if e.message == 'No such process' | |
puts "No such process : #{pid} ! check ps aux #{pid}" | |
end | |
else | |
if res == 1 | |
puts 'Aready running unicorn' | |
else | |
puts 'Somethig Wrong' | |
end | |
end | |
end | |
else | |
if File.exists? old_pid_file | |
puts 'Aready Exist Old Pid. Please check ps aux | grep "unicorn"' | |
else | |
puts 'Not running unicorn.' | |
end | |
end | |
end | |
def method_missing(action, *args) | |
usage | |
end | |
private | |
def is_unicorn_stop? | |
if File.exists? @pid_file | |
old_pid = open(@pid_file).read.to_i | |
master_process = `ps aux #{old_pid}` | |
if master_process.empty? | |
puts 'Not running unicorn' | |
return true | |
end | |
else | |
puts 'No pid file. Start unicorn' | |
return true | |
end | |
return false | |
end | |
def is_unicorn_running? | |
if File.exists? @pid_file | |
old_pid = open(@pid_file).read.to_i | |
master_process = `ps aux #{old_pid}` | |
unless master_process.empty? | |
puts 'Aready running' | |
return true | |
end | |
end | |
return false | |
end | |
def is_unicorn_restarting? | |
if File.exists? "#{@pid_file}.oldbin" | |
puts 'Still restarting' | |
return true | |
end | |
return false | |
end | |
def is_timeout?(timeout, count) | |
if count > timeout | |
puts 'Timeout' | |
return true | |
end | |
return false | |
end | |
end | |
## script | |
# initial | |
action = ARGV.shift || '' | |
rails_env = 'production' | |
rails_home = "#{ENV['HOME']}/app" | |
timeout = 30 | |
opt = OptionParser.new(ARGV) | |
opt.on('-e rails_env') {|e| rails_env = e } | |
opt.on('-h rails_home') {|h| rails_home = h } | |
opt.on('-t timeout_sec') {|t| timeout = t.to_i } | |
opt.parse! | |
unicorn = UnicornStarter.new(rails_env, rails_home, timeout) | |
unicorn.send action | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment