Skip to content

Commit

Permalink
simplify/cleanup fifo use
Browse files Browse the repository at this point in the history
  • Loading branch information
dzuelke committed Jan 27, 2015
1 parent ec35e33 commit 7c30f7c
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
13 changes: 7 additions & 6 deletions bin/heroku-hhvm-apache2
Original file line number Diff line number Diff line change
Expand Up @@ -232,33 +232,34 @@ httpd_config=$(php_passthrough "$httpd_config")
# make a shared pipe; we'll write the name of the process that exits to it once that happens, and wait for that event below
# this particular call works on Linux and Mac OS (will create a literal ".XXXXXX" on Mac, but that doesn't matter).
wait_pipe=$(mktemp -t "heroku.waitpipe-$PORT.XXXXXX" -u)
rm -rf $wait_pipe
rm -f $wait_pipe
mkfifo $wait_pipe
exec 3<> $wait_pipe

# trap SIGINT/SIGQUIT (ctrl+c or ctrl+\ on the console), SIGTERM, and EXIT (upon failure of any command due to set -e, or because of the exit 1 at the very end), kill subshell child processes, then subshells
# 1) restore EXIT trap immediately, or the exit at the end of the line will trigger this trap again
# 2) kill childrens' child processes (the stuff running inside the sub-shells) using xargs because this is easier (-P expects a comma separated list); the || true prevents premature exit (set -e) if one of those doesn't have children anymore (it's likely that's why we're hitting this bit of code in the first place), and redirect all to /dev/null as usage help when no args given (because jobs -p was empty) is sometimes (Linux) printed to STDOUT
# 3) kill child processes (that's the sub-shells); it's likely that some of them have already disappeared, so xarg || true it too and suppress "no such process" complaints by sending them to /dev/null
# FIXME: this doesn't currently fire when the subshells themselves are terminated
# TODO: for extra brownie points, move to a function and curry for each given signal, passing the signal in as an arg, so we can use different exit codes or messages
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; rm -f ${wait_pipe} || true; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT

# launch processes. all run using || true to prevent premature exit of the subshell (from set -e) regardless of exit status
# after a subprocess terminates (because it was killed or because it crashed or because it quit voluntarily), we write the name to FD 3 (because programs could output something on FD 1 (STDOUT) or FD 2 (STDERR)) and send that to the shared pipe (mkfifo) above, and a read command further down waits for something to come in on the shared pipe

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
[[ $verbose ]] && echo "Starting log redirection..." >&2
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) &
# start HHVM; write "hhvm" to the shared pipe if it exits
echo "Starting hhvm..." >&2
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe &
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) &
# wait a few seconds for HHVM to finish initializing; otherwise an early request might break Apache with the FastCGI pipe not being ready
# start apache; write "httpd" to the shared pipe if it exits
echo "Starting httpd..." >&2
( sleep 2; httpd -D NO_DETACH -c "Include $httpd_config" || true; echo "httpd" >&3; ) 3> $wait_pipe &
( sleep 2; httpd -D NO_DETACH -c "Include $httpd_config" || true; echo "httpd" >&3; ) &

# wait for something to come from the shared pipe, which means that the given process was killed or has failed
read exitproc < $wait_pipe
read exitproc <&3
# we'll only reach this if one of the processes above has terminated
echo "Process exited unexpectedly: $exitproc" >&2

Expand Down
13 changes: 7 additions & 6 deletions bin/heroku-hhvm-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -232,33 +232,34 @@ nginx_config=$(php_passthrough "$nginx_config")
# make a shared pipe; we'll write the name of the process that exits to it once that happens, and wait for that event below
# this particular call works on Linux and Mac OS (will create a literal ".XXXXXX" on Mac, but that doesn't matter).
wait_pipe=$(mktemp -t "heroku.waitpipe-$PORT.XXXXXX" -u)
rm -rf $wait_pipe
rm -f $wait_pipe
mkfifo $wait_pipe
exec 3<> $wait_pipe

# trap SIGINT/SIGQUIT (ctrl+c or ctrl+\ on the console), SIGTERM, and EXIT (upon failure of any command due to set -e, or because of the exit 1 at the very end), kill subshell child processes, then subshells
# 1) restore EXIT trap immediately, or the exit at the end of the line will trigger this trap again
# 2) kill childrens' child processes (the stuff running inside the sub-shells) using xargs because this is easier (-P expects a comma separated list); the || true prevents premature exit (set -e) if one of those doesn't have children anymore (it's likely that's why we're hitting this bit of code in the first place), and redirect all to /dev/null as usage help when no args given (because jobs -p was empty) is sometimes (Linux) printed to STDOUT
# 3) kill child processes (that's the sub-shells); it's likely that some of them have already disappeared, so xarg || true it too and suppress "no such process" complaints by sending them to /dev/null
# FIXME: this doesn't currently fire when the subshells themselves are terminated
# TODO: for extra brownie points, move to a function and curry for each given signal, passing the signal in as an arg, so we can use different exit codes or messages
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; rm -f ${wait_pipe} || true; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT

# launch processes. all run using || true to prevent premature exit of the subshell (from set -e) regardless of exit status
# after a subprocess terminates (because it was killed or because it crashed or because it quit voluntarily), we write the name to FD 3 (because programs could output something on FD 1 (STDOUT) or FD 2 (STDERR)) and send that to the shared pipe (mkfifo) above, and a read command further down waits for something to come in on the shared pipe

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
[[ $verbose ]] && echo "Starting log redirection..." >&2
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) &
# start HHVM; write "hhvm" to the shared pipe if it exits
echo "Starting hhvm..." >&2
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe &
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) &
# wait a few seconds for HHVM to finish initializing; otherwise an early request might break nginx with the FastCGI pipe not being ready
# start nginx; write "nginx" to the shared pipe if it exits
echo "Starting nginx..." >&2
( sleep 2; nginx -g "daemon off; include $nginx_config;" || true; echo "nginx" >&3; ) 3> $wait_pipe &
( sleep 2; nginx -g "daemon off; include $nginx_config;" || true; echo "nginx" >&3; ) &

# wait for something to come from the shared pipe, which means that the given process was killed or has failed
read exitproc < $wait_pipe
read exitproc <&3
# we'll only reach this if one of the processes above has terminated
echo "Process exited unexpectedly: $exitproc" >&2

Expand Down
13 changes: 7 additions & 6 deletions bin/heroku-php-apache2
Original file line number Diff line number Diff line change
Expand Up @@ -273,34 +273,35 @@ httpd_config=$(php_passthrough "$httpd_config")
# make a shared pipe; we'll write the name of the process that exits to it once that happens, and wait for that event below
# this particular call works on Linux and Mac OS (will create a literal ".XXXXXX" on Mac, but that doesn't matter).
wait_pipe=$(mktemp -t "heroku.waitpipe-$PORT.XXXXXX" -u)
rm -rf $wait_pipe
rm -f $wait_pipe
mkfifo $wait_pipe
exec 3<> $wait_pipe

# trap SIGINT/SIGQUIT (ctrl+c or ctrl+\ on the console), SIGTERM, and EXIT (upon failure of any command due to set -e, or because of the exit 1 at the very end), kill subshell child processes, then subshells
# 1) restore EXIT trap immediately, or the exit at the end of the line will trigger this trap again
# 2) kill childrens' child processes (the stuff running inside the sub-shells) using xargs because this is easier (-P expects a comma separated list); the || true prevents premature exit (set -e) if one of those doesn't have children anymore (it's likely that's why we're hitting this bit of code in the first place), and redirect all to /dev/null as usage help when no args given (because jobs -p was empty) is sometimes (Linux) printed to STDOUT
# 3) kill child processes (that's the sub-shells); it's likely that some of them have already disappeared, so xarg || true it too and suppress "no such process" complaints by sending them to /dev/null
# FIXME: this doesn't currently fire when the subshells themselves are terminated
# TODO: for extra brownie points, move to a function and curry for each given signal, passing the signal in as an arg, so we can use different exit codes or messages
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; rm -f ${wait_pipe} || true; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT

# launch processes. all run using || true to prevent premature exit of the subshell (from set -e) regardless of exit status
# after a subprocess terminates (because it was killed or because it crashed or because it quit voluntarily), we write the name to FD 3 (because programs could output something on FD 1 (STDOUT) or FD 2 (STDERR)) and send that to the shared pipe (mkfifo) above, and a read command further down waits for something to come in on the shared pipe

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
[[ $verbose ]] && echo "Starting log redirection..." >&2
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" | strip_fpm_child_said 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" | strip_fpm_child_said 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) &
# start FPM; write "php-fpm" to the shared pipe if it exits
echo "Starting php-fpm..." >&2
unset -f php-fpm # remove the alias we made earlier that would prevent newrelic from starting on php-fpm -v
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe &
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) &
# wait a few seconds for FPM to finish initializing; otherwise an early request might break Apache with the FastCGI pipe not being ready
# start apache; write "httpd" to the shared pipe if it exits
echo "Starting httpd..." >&2
( sleep 2; httpd -D NO_DETACH -c "Include $httpd_config" || true; echo "httpd" >&3; ) 3> $wait_pipe &
( sleep 2; httpd -D NO_DETACH -c "Include $httpd_config" || true; echo "httpd" >&3; ) &

# wait for something to come from the shared pipe, which means that the given process was killed or has failed
read exitproc < $wait_pipe
read exitproc <&3
# we'll only reach this if one of the processes above has terminated
echo "Process exited unexpectedly: $exitproc" >&2

Expand Down
13 changes: 7 additions & 6 deletions bin/heroku-php-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -273,34 +273,35 @@ nginx_config=$(php_passthrough "$nginx_config")
# make a shared pipe; we'll write the name of the process that exits to it once that happens, and wait for that event below
# this particular call works on Linux and Mac OS (will create a literal ".XXXXXX" on Mac, but that doesn't matter).
wait_pipe=$(mktemp -t "heroku.waitpipe-$PORT.XXXXXX" -u)
rm -rf $wait_pipe
rm -f $wait_pipe
mkfifo $wait_pipe
exec 3<> $wait_pipe

# trap SIGINT/SIGQUIT (ctrl+c or ctrl+\ on the console), SIGTERM, and EXIT (upon failure of any command due to set -e, or because of the exit 1 at the very end), kill subshell child processes, then subshells
# 1) restore EXIT trap immediately, or the exit at the end of the line will trigger this trap again
# 2) kill childrens' child processes (the stuff running inside the sub-shells) using xargs because this is easier (-P expects a comma separated list); the || true prevents premature exit (set -e) if one of those doesn't have children anymore (it's likely that's why we're hitting this bit of code in the first place), and redirect all to /dev/null as usage help when no args given (because jobs -p was empty) is sometimes (Linux) printed to STDOUT
# 3) kill child processes (that's the sub-shells); it's likely that some of them have already disappeared, so xarg || true it too and suppress "no such process" complaints by sending them to /dev/null
# FIXME: this doesn't currently fire when the subshells themselves are terminated
# TODO: for extra brownie points, move to a function and curry for each given signal, passing the signal in as an arg, so we can use different exit codes or messages
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT
trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; rm -f ${wait_pipe} || true; jobs -p | xargs -n1 pkill -TERM -P &> /dev/null || true; jobs -p | xargs -n1 kill -TERM 2> /dev/null || true; exit' SIGINT SIGQUIT SIGTERM EXIT

# launch processes. all run using || true to prevent premature exit of the subshell (from set -e) regardless of exit status
# after a subprocess terminates (because it was killed or because it crashed or because it quit voluntarily), we write the name to FD 3 (because programs could output something on FD 1 (STDOUT) or FD 2 (STDERR)) and send that to the shared pipe (mkfifo) above, and a read command further down waits for something to come in on the shared pipe

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
[[ $verbose ]] && echo "Starting log redirection..." >&2
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" | strip_fpm_child_said 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" | strip_fpm_child_said 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) &
# start FPM; write "php-fpm" to the shared pipe if it exits
echo "Starting php-fpm..." >&2
unset -f php-fpm # remove the alias we made earlier that would prevent newrelic from starting on php-fpm -v
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe &
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) &
# wait a few seconds for FPM to finish initializing; otherwise an early request might break nginx with the FastCGI pipe not being ready
# start nginx; write "nginx" to the shared pipe if it exits
echo "Starting nginx..." >&2
( sleep 2; nginx -g "daemon off; include $nginx_config;" || true; echo "nginx" >&3; ) 3> $wait_pipe &
( sleep 2; nginx -g "daemon off; include $nginx_config;" || true; echo "nginx" >&3; ) &

# wait for something to come from the shared pipe, which means that the given process was killed or has failed
read exitproc < $wait_pipe
read exitproc <&3
# we'll only reach this if one of the processes above has terminated
echo "Process exited unexpectedly: $exitproc" >&2

Expand Down

0 comments on commit 7c30f7c

Please sign in to comment.