Report abuse


			
#!/bin/bash
 
# /engineyard/bin/merb_thin
 
# This script starts and stops a named thin server on a specified socket
# This script belongs in /engineyard/bin/thin
# Do not forget to ensure this script is executable: 
#   $ chmod a+x /engineyard/bin/merb_thin
 
export PATH=/bin:/usr/bin:/usr/local/bin:/usr/local:/opt/bin:$PATH
 
usage() {
  echo "Usage: $0 {start, stop} application socket environment"
  exit 1
}
 
if [ $# -lt 4 ]; then
  usage
fi
 
# Parameters: 
# $0 : /engineyard/bin/thin
# $1 : start/stop
# $2 : application
# $3 : socket
# $4 : environment
action=$1 ; application=$2 ; socket=$3 ; environment=$4
 
#
# Setup
#
log_dir="/var/log/engineyard/$application"
log_file="$log_dir/thin.control.log"
app_dir="/data/$application/current"
app_log_file="$app_dir/log/$environment.log"
pid_dir="/var/run/engineyard/$application"
socket_dir="/var/run/engineyard/$application"
pid_file="thin.pid"
socket_file="$application.thin.$socket.sock"
socket_checker="/engineyard/bin/socket_check"
 
mkdir -p $log_dir
touch $log_file
 
#
# Utility functions
# 
 
log() {
  echo $1 >> $log_file
}
 
set_running_pid() {
  running_pid=`ps auxww | grep "$application/$application.thin.$socket.sock" | grep -v "grep"| awk '{print $2}'`
  log "running_pid: $running_pid"
  return $running_pid
}
 
set_pid_file_pid() {
  if [ -f "$pid_dir/$pid_file" ]; then
    pid_file_pid=`cat $pid_dir/$pid_file`
  fi
  log "pid_file_pid: $pid_file_pid"
  return $pid_file_pid
}
 
start_thin() {
  log "Starting merb_thin applicatin $application on socket $socket with environment $environment."
  /usr/bin/merb -d -a thin -L $app_log_file -e $environment -m $app_dir -P $pid_dir/$pid_file -h $socket_dir/$socket_file
}
 
stop_thin() {
  log "Stopping thin application $application running on socket $socket."
  /usr/bin/thin stop -P $1
}
 
quit_thin() {
  log "Sending SIGQUIT to thin $application on sock $socket."
  kill -QUIT $1 2>/dev/null; true
}
 
force_kill_thin() {
  log "Force killing $1 to ensure it has stopped."
  kill -9 $1 2>/dev/null; true
}
 
socket_check() {
  if [ -S "$socket_dir/$socket_file" ] ; then
    log "The socket file exists and is a socket then check it for a response"
    log "Checking socket ($socket_checker $socket_dir/$socket_file)"
    $socket_checker $socket_dir/$socket_file
    return $?
  else
    log "Socket file $socket_dir/$socket_file does not exist and/or is not a socket."
    return 1
  fi
}
 
write_pid_file() {
  log "Writing $1 to the pidfile: $pid_dir/$pid_file"
  echo $1 > $pid_dir/$pid_file
}
 
#
# Main Logic
#
 
# If the pid_file exists check for running thin
# also ensure that it represents the running thin
 
# Exit if the application does not exist.
if [ ! -d "$app_dir" ]; then
  log "$app_dir does not exist."
  usage
fi
 
set_running_pid
set_pid_file_pid
 
case "$action" in
  start)
    if [ -f "$pid_dir/$pid_file" ]; then
      log "Pidfile $pid_dir/$pid_file exists"
      if [ "$running_pid" == "$pid_file_pid" ] ; then
        log "Pidfile matches the found running pid"
        if [ socket_check -eq 0 ]; then
          log "The running thin was responsive so write it's pid to the pidfile and exit with success"
          write_pid_file $running_pid
         log "The thin application $application is already running on socket $socket, aborting."
          exit 0
        else
          log "The thin was unresponsive, force kill to make sure it is not running and start a new thin."
          force_kill_thin $pid_file_pid
          force_kill_thin $running_pid
          start_thin
        fi
      else
        log "The pidfile pid does not match the running thin's pid."
        force_kill_thin $pid_file_pid
        if [ socket_check -eq 0 ]; then
          log "The running thin was responsive so write it's pid to the pidfile and exit with success"
          write_pid_file $running_pid
          log "The thin application $application is already running on socket $socket, aborting."
          exit 0
        else
          log "The running thin was unresponsive, force kill to make sure it is not running and start a new thin."
          force_kill_thin $pid_file_pid
          force_kill_thin $running_pid
          start_thin
        fi
      fi
    else
      log "The pidfile does not exist"
      if [ -n "$running_pid" ] && [ "$running_pid" -gt 0 ]; then 
        log "There is a thin running"
        if [ socket_check -eq 0 ]; then
          log "The thin was responsive on the socket is responsive on the socket"
          write_pid_file $running_pid
          log "The thin application $application is already running on socket $socket, aborting."
          exit 0
        else
          log "The running thin was unresponsive on the socket, force kill it and start a new thin"
          force_kill_thin $running_pid
          start_thin
        fi
      else
        log "No thin was running, start a new thin"
        start_thin
      fi
    fi
  ;;
  
  stop)
    if [ -n "$pid_file_pid" ] && [ "$pid_file_pid" -gt 0 ]; then
      stop_thin $pid_file_pid
    fi
    if [ -n "$running_pid" ] && [ "$running_pid" -gt 0 ]; then
      stop_thin $running_pid
    fi
    log "sleeping for 5 seconds"
    log "If a request is running longer that 5s then it's an app issue :)"
    sleep 5
    log "we will now ensure the thin has quit (killing both just in case there are two running from some mishap)"
    force_kill_thin $running_pid
    force_kill_thin $pid_file_pid
  ;;
 
  *)
    usage
  ;;
esac
 
exit 0