Reduce raciness in the init script and add LSB tags.
However, the systemd examples should be race-free and
safer (if one feels safe using systemd :P)
---
 examples/init.sh        | 43 +++++++++++++++++++++++++++++++++---------
 examples/logrotate.conf |  5 +++++
 examples/yahns.socket   | 17 +++++++++++++++++
 examples/[email protected] | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 9 deletions(-)
 create mode 100644 examples/yahns.socket
 create mode 100644 examples/[email protected]

diff --git a/examples/init.sh b/examples/init.sh
index 9464220..6fe1ae6 100644
--- a/examples/init.sh
+++ b/examples/init.sh
@@ -2,8 +2,14 @@
 # To the extent possible under law, Eric Wong has waived all copyright and
 # related or neighboring rights to this examples
 set -e
-# Example init script, this can be used with nginx, too,
-# since nginx and yahns accept the same signals
+### BEGIN INIT INFO
+# Provides:          yahns
+# Required-Start:    $local_fs $network
+# Required-Stop:     $local_fs $network
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Start/stop yahns Ruby app server
+### END INIT INFO
 
 # Feel free to change any of the following variables for your app:
 TIMEOUT=${TIMEOUT-60}
@@ -11,21 +17,22 @@ APP_ROOT=/home/x/my_app/current
 PID=$APP_ROOT/tmp/pids/yahns.pid
 CMD="/usr/bin/yahns -D -c $APP_ROOT/config/yahns.rb"
 INIT_CONF=$APP_ROOT/config/init.conf
+UPGRADE_DELAY=${UPGRADE_DELAY-2}
 action="$1"
 set -u
 
 test -f "$INIT_CONF" && . $INIT_CONF
 
-old_pid="$PID.oldbin"
+OLD="$PID.oldbin"
 
 cd $APP_ROOT || exit 1
 
 sig () {
-       test -s "$PID" && kill -$1 `cat $PID`
+       test -s "$PID" && kill -$1 $(cat $PID)
 }
 
 oldsig () {
-       test -s $old_pid && kill -$1 `cat $old_pid`
+       test -s "$OLD" && kill -$1 $(cat $OLD)
 }
 
 case $action in
@@ -47,18 +54,36 @@ restart|reload)
        $CMD
        ;;
 upgrade)
-       if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
+       if oldsig 0
+       then
+               echo >&2 "Old upgraded process still running with $OLD"
+               exit 1
+       fi
+
+       cur_pid=
+       if test -s "$PID"
+       then
+               cur_pid=$(cat $PID)
+       fi
+
+       if test -n "$cur_pid" &&
+                       kill -USR2 "$cur_pid" &&
+                       sleep $UPGRADE_DELAY &&
+                       new_pid=$(cat $PID) &&
+                       test x"$new_pid" != x"$cur_pid" &&
+                       kill -0 "$new_pid" &&
+                       kill -QUIT "$cur_pid"
        then
                n=$TIMEOUT
-               while test -s $old_pid && test $n -ge 0
+               while kill -0 "$cur_pid" 2>/dev/null && test $n -ge 0
                do
                        printf '.' && sleep 1 && n=$(( $n - 1 ))
                done
                echo
 
-               if test $n -lt 0 && test -s $old_pid
+               if test $n -lt 0 && kill -0 "$cur_pid" 2>/dev/null
                then
-                       echo >&2 "$old_pid still exists after $TIMEOUT seconds"
+                       echo >&2 "$cur_pid still running after $TIMEOUT seconds"
                        exit 1
                fi
                exit 0
diff --git a/examples/logrotate.conf b/examples/logrotate.conf
index ebc92a5..b0d1351 100644
--- a/examples/logrotate.conf
+++ b/examples/logrotate.conf
@@ -25,6 +25,11 @@
        # config.  yahns supports the USR1 signal and we send it
        # as our "lastaction" action:
        lastaction
+               # systemd users do not have PID files,
+               # only signal the @1 process since the @2 is short-lived
+               # and only runs while @1 is restarting.
+               systemctl kill -s SIGUSR1 [email protected]
+
                # assuming your pid file is in /var/run/yahns_app/pid
                pid=/var/run/yahns_app/pid
                test -s $pid && kill -USR1 "$(cat $pid)"
diff --git a/examples/yahns.socket b/examples/yahns.socket
new file mode 100644
index 0000000..6455b41
--- /dev/null
+++ b/examples/yahns.socket
@@ -0,0 +1,17 @@
+# ==> /etc/systemd/system/yahns.socket <==
+[Unit]
+Description = yahns sockets
+
+[Socket]
+
+# yahns can handle an arbitrary number of listen sockets,
+# so I prefer to keep listeners for IPv4 and IPv6 separate
+# to avoid ugly IPv4-mapped-IPv6 addresses for IPv4 clients:
+# (e.g ":ffff:10.0.0.1" instead of just "10.0.0.1").
+ListenStream = 0.0.0.0:443
+BindIPv6Only = ipv6-only
+ListenStream = [::]:443
+Service = [email protected]
+
+[Install]
+WantedBy = sockets.target
diff --git a/examples/[email protected] b/examples/[email protected]
new file mode 100644
index 0000000..1ee010f
--- /dev/null
+++ b/examples/[email protected]
@@ -0,0 +1,50 @@
+# ==> /etc/systemd/system/[email protected] <==
+# Since SIGUSR2 upgrades do not work under systemd, this service
+# file allows starting two (or more) simultaneous services
+# during upgrade (e.g. yahns@1 and yahns@2) with the intention
+# that they are both running during the upgrade process.
+#
+# This allows upgrading without downtime, using yahns@2 as a
+# temporary hot spare:
+#
+#   systemctl start yahns@2
+#   sleep 2 # wait for yahns@2 to boot, increase as necessary for big apps
+#   systemctl restart yahns@1
+#   sleep 2 # wait for yahns@1 to warmup
+#   systemctl stop yahns@2
+
+[Unit]
+Description = yahns Ruby server %i
+Wants = yahns.socket
+After = yahns.socket
+
+[Service]
+# yahns can handle lots of open files:
+LimitNOFILE = 32768
+LimitCORE = infinity
+
+# The listen socket we give yahns should be blocking for optimal
+# load distribution between processes under the Linux kernel.
+# NonBlocking is false by default in systemd, but we specify it
+# here anyways to discourage users from blindly changing it.
+Sockets = yahns.socket
+NonBlocking = false
+
+# bundler users must use the "--keep-file-descriptors" switch, here:
+# ExecStart = /path/to/bin/bundle exec --keep-file-descriptors yahns -c ...
+ExecStart = /path/to/bin/yahns -c /path/to/yahns.conf.rb
+KillSignal = SIGQUIT
+User = www-data
+Group = www-data
+ExecReload = /bin/kill -HUP $MAINPID
+
+# this should match the shutdown_timeout value in yahns_config(5)
+TimeoutStopSec = 600
+
+# Only kill the master process, it may be harmful to signal
+# workers via default "control-group" setting since some
+# Ruby extensions and applications misbehave on interrupts
+KillMode = process
+
+[Install]
+WantedBy = multi-user.target
-- 
EW

--
unsubscribe: [email protected]
archive: https://yhbt.net/yahns-public/

Reply via email to