Created
January 29, 2012 09:49
-
-
Save tjl2/1698074 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
#!/bin/sh | |
# | |
# This script starts and stops the Dj daemon | |
# This script belongs in /engineyard/bin/dj | |
# | |
PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH | |
CURDIR=`pwd` | |
usage() { | |
echo "Usage: $0 <appname> {start|stop} enviroment [name maximum_priority minimum_priority]" | |
exit 1 | |
} | |
if [ $# -lt 3 ]; then usage; fi | |
if [ $4 ]; then | |
NAME="_$4" | |
if [ $5 ]; then | |
OPTIONS=":max_priority=>$5" | |
if [ $6 ]; then | |
OPTIONS="$OPTIONS,:min_priority=>$6" | |
fi | |
OPTIONS="{$OPTIONS}" | |
fi | |
fi | |
if [ "`whoami`" != "root" ]; then | |
logger -t `basename $0` -s "Must be run as root" | |
exit 1 | |
fi | |
## Function definitions - casual readers encouraged to skip this ## | |
rm_lockfile(){ | |
if [ -e $LOCK_FILE ]; then | |
logger -t "monit_dj:$WORKER[$$]" "removing $LOCK_FILE for `cat $LOCK_FILE`" | |
rm $LOCK_FILE | |
fi | |
} | |
lock(){ | |
RESULT=0 | |
if [ -e $LOCK_FILE ]; then | |
LAST_LOCK_PID=`cat $LOCK_FILE` | |
if [ -n $LAST_LOCK_PID -a -z "`ps axo pid|grep $LAST_LOCK_PID`" -a -f $LOCK_FILE ];then | |
sleep 1 | |
logger -t "monit-dj:$WORKER[$$]" "Removing stale lock file for $WORKER ($LAST_LOCK_PID)" | |
rm $LOCK_FILE 2>&1 | |
else | |
logger -t "monit-dj:$WORKER[$$]" "Monit already messing with $WORKER ($LAST_LOCK_PID)" | |
RESULT=1 | |
exit_cleanly | |
fi | |
fi | |
echo $$ > $LOCK_FILE | |
} | |
exit_cleanly() { | |
cd $CURDIR | |
logger -t "mont-dj:$WORKER[$$]" "exiting wrapper cleanly with $RESULT" | |
exit $RESULT | |
} | |
unlock_and_exit_cleanly(){ | |
rm_lockfile | |
exit_cleanly | |
} | |
## End function definitions ## | |
#set -x | |
WORKER=$1$NAME | |
LOCK_FILE="/tmp/$WORKER.monit-lock" | |
BUNDLER_COMMAND="ruby" | |
RAILS_ROOT=/data/$1/current | |
if [ -d $RAILS_ROOT ]; then | |
if [ -f $RAILS_ROOT/Gemfile ]; then | |
if [ -d $RAILS_ROOT/ey_bundler_binstubs ]; then | |
PATH=$RAILS_ROOT/ey_bundler_binstubs:$PATH | |
else | |
BUNDLER_COMMAND="bundle exec ruby" | |
fi | |
fi | |
RAILS_ENV=$3 | |
export $RAILS_ENV | |
RUNNER='runner' | |
#RAILS_SCRIPTS="$RAILS_ROOT/script" | |
RAILS_SCRIPTS="$RAILS_ROOT/script" | |
[ -f $RAILS_SCRIPTS/rails ] && chmod a+x $RAILS_SCRIPTS/rails && RUNNER="rails runner" | |
cd $RAILS_ROOT | |
PID_FILE=/var/run/engineyard/dj/$1/dj$NAME.pid | |
USER=`stat -c"%U" /data/$1/current/` | |
HOME="/home/$USER" ; export HOME | |
RESULT=0 | |
GRACE_TIME=${GRACE_TIME:-60} | |
let "GRACE_TIME=$GRACE_TIME*4" | |
mkdir -p /var/run/engineyard/dj/$1 | |
case "$2" in | |
start) | |
lock | |
cd $RAILS_ROOT | |
HAS_DJ_COMMAND="RAILS_ENV=$RAILS_ENV $BUNDLER_COMMAND $RAILS_SCRIPTS/$RUNNER -e $RAILS_ENV \"require 'delayed/command';puts defined?(Delayed::Command)\" 2>/dev/null" | |
has_dj_command=$(sudo -u $USER -H /bin/bash -c "$HAS_DJ_COMMAND") | |
if [[ $has_dj_command == "constant" ]];then | |
OPTIONS=${OPTIONS:-[]} | |
HAS_BEFORE_FORK="RAILS_ENV=$RAILS_ENV $BUNDLER_COMMAND $RAILS_SCRIPTS/$RUNNER -e $RAILS_ENV \"require 'delayed/worker';puts Delayed::Worker.respond_to?(:before_fork)\" 2>/dev/null" | |
has_before_fork=$(sudo -u $USER -H /bin/bash -c "$HAS_BEFORE_FORK") | |
if [[ $has_before_fork == "true" ]];then | |
RUNNER_COMMAND="require 'delayed/command';Delayed::Worker.before_fork;Delayed::Command.new($OPTIONS).run" | |
else | |
RUNNER_COMMAND="require 'delayed/command';Delayed::Command.new($OPTIONS).run" | |
fi | |
else | |
RUNNER_COMMAND="Delayed::Worker.new($OPTIONS).start" | |
fi | |
COMMAND="$BUNDLER_COMMAND $RAILS_SCRIPTS/$RUNNER -e $RAILS_ENV \"$RUNNER_COMMAND\"" | |
logger -t "monit-dj:$WORKER[$$]" "DJ Worker starting from $PPID" | |
if [ -f $PID_FILE ]; then | |
PID=`cat $PID_FILE` | |
if [ -n "$PID" ];then | |
logger -t "monit-dj:$WORKER[$$]" "There is already a PID file for delayed Job [$PID]" | |
if [ -d /proc/$PID ]; then | |
logger -t "monit-dj:$WORKER[$$]" "Dj worker is already running with PID of $PID" | |
RESULT=1 | |
else | |
logger -t "monit-dj:$WORKER[$$]" "Removing stale pid file for $WORKER" | |
rm -f $PID_FILE | |
fi | |
fi | |
fi | |
if [ $RESULT -eq 0 ]; then | |
logger -t "monit-dj:$WORKER[$$]" "issuing command $COMMAND in $PWD for $USER" | |
sudo -u $USER -H /bin/bash -c "$COMMAND" & | |
NEW_PID=$! | |
RESULT=$? | |
logger -t "monit-dj:$WORKER[$$]" "$WORKER started as $NEW_PID : $RESULT" | |
echo $NEW_PID > $PID_FILE | |
fi | |
unlock_and_exit_cleanly | |
;; | |
stop) | |
lock | |
logger -t "monit_dj:$WORKER[$$]" "Stopping DJ worker:" | |
if [ -f $PID_FILE ]; then | |
PID=$(cat $PID_FILE) | |
# Find children | |
WORKER_PID=$(ps axo pid,ppid,command|awk '$2=='$PID' {print $1}') | |
kill -15 $PID $PPID; # kill worker and any child that it may have at this very moment | |
logger -t "monit-dj:$WORKER[$$]" "Stopping DJ Worker Process $PID $PPID" | |
SLEEP_COUNT=0 | |
while [ -e /proc/$PID ]; do | |
sleep .25 | |
let "SLEEP_COUNT+=1" | |
let "REPORT_TIME = $SLEEP_COUNT%4" | |
if(( "$SLEEP_COUNT" > $GRACE_TIME )); then | |
logger -t "monit-dj:$WORKER[$$]" "Stopping DJ Worker Child Process $PID wait exceeded, killing it" | |
kill -9 $PID 2>/dev/null; true | |
break | |
elif(( $REPORT_TIME == 0 ));then | |
let "RUNTIME = $SLEEP_COUNT/4" | |
logger -t "monit-dj:$WORKER[$$]" "Waiting for $PID to die ( for $RUNTIME seconds now)" | |
fi | |
done | |
fi | |
[ -e "$PID_FILE" ] && rm -f $PID_FILE | |
unlock_and_exit_cleanly | |
;; | |
*) | |
usage | |
;; | |
esac | |
else | |
echo "/data/$1/current doesn't exist." | |
usage | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment