#!upstart # /etc/init/{{service}}.conf # # {{service}} - Provisioned using forever-service # # CLI {{cli}} # Working Directory {{cwd}} # description "forever-service startup script for node script based service {{service}}, uses forever to start the service" {% if applyUlimits %} limit nofile 20000 20000 {% endif %} env FOREVER_ROOT={{foreverRoot}} start on (local-filesystems and net-device-up IFACE=eth0) stop on shutdown expect fork # Check if any of $pid (could be plural) are running env LOGFILE="/var/log/{{service}}.log" # introduce some gaps between restarts and throttle continous restarts env MIN_UPTIME="{{minUptime|default('5000')}}" env SPIN_SLEEP_TIME="{{spinSleepTime|default('2000')}}" # kill signal: Since default needs to be SIGTERM, it is important that services gracefully shutdown, # specially if they are doing transactions or other work which should not be interuppted in between # for exceptional situation where you dont care about abrupt shutdown, SIGKILL should be used env KILL_SIGNAL="{{killSignal|default('SIGTERM')}}" # Wait time afer with SIGKILL will be sent to the process, in case SIGTERM is not fully finished # This is required since when we use SIGTERM, some times if there is problem in code, it might take lot of time for process to exit # or process may never exit, in such siutation we have to forcebly kill it so that shutdown or service restart can be done appropriately # this wait time is in millisecond env KILLWAITTIME={{forceKillWaitTime|default('5000')}} chdir {{cwd}} {%- if envVarsArray|default(false) %} {%- for v in envVarsArray %} env {{ v }} {%- endfor %} {%- endif %} exec {{foreverPath}}forever -a -l $LOGFILE --minUptime $MIN_UPTIME --spinSleepTime $SPIN_SLEEP_TIME --killSignal $KILL_SIGNAL {{foreverOptions|default('')}} --uid {{service}} start {{script|default('app.js')}} {{scriptOptions|default('')}} post-start script echo "{{service}} started" end script pre-stop script echo "Shutting down {{service}}: " STATUS=$({{foreverPath}}forever --plain list | sed 's/data:\(\s*\[[0-9]*\]\s*\({{service}}\)\s.*\)/\2-status:\1/;tx;d;:x') if [ -z "$STATUS" ]; then echo "Not running" return 0 fi # PID=$(<$PIDFILE) - Changed to detection based on actual PID from forever, sicne due to watchDirectory pid could dynamically change PID=$({{foreverPath}}forever --plain list | sed -n -e '/data:\s*\[[0-9]*\]\s\({{service}}\)\s/p' | awk '{print $7}') if [ -z "$PID" ]; then echo "Could not get pid" return 0 fi {{foreverPath}}forever stop {{service}} & killtree() { local _pid=$1 local _sig=${2:--TERM} kill -stop ${_pid} # needed to stop quickly forking parent from producing children between child killing and parent killing for _child in $(ps -o pid --no-headers --ppid ${_pid}); do killtree ${_child} ${_sig} done kill -${_sig} ${_pid} } CURRENTWAITTIME=$KILLWAITTIME # wait for some time before forcefully killing the process while [ $CURRENTWAITTIME -gt 0 ]; do #check if the process is still running if [ ! -d "/proc/$PID" ]; then echo "{{service}} shutdown" # if not running we can break, since no more wait is needed, service is stopped break fi sleep 1 CURRENTWAITTIME=$(( $CURRENTWAITTIME - 1000)) done if [ -d "/proc/$PID" ]; then killtree $PID 9 echo "{{service}} Forced shutdown" fi end script