yahns Ruby server user/dev discussion
 help / color / Atom feed
* [PATCH] update init and add systemd examples
@ 2016-07-07  1:22 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2016-07-07  1:22 UTC (permalink / raw)
  To: yahns-public

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/yahns@.service | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 9 deletions(-)
 create mode 100644 examples/yahns.socket
 create mode 100644 examples/yahns@.service

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 yahns@1.service
+
 		# 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 = yahns@1.service
+
+[Install]
+WantedBy = sockets.target
diff --git a/examples/yahns@.service b/examples/yahns@.service
new file mode 100644
index 0000000..1ee010f
--- /dev/null
+++ b/examples/yahns@.service
@@ -0,0 +1,50 @@
+# ==> /etc/systemd/system/yahns@.service <==
+# 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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-07  1:22 [PATCH] update init and add systemd examples Eric Wong

yahns Ruby server user/dev discussion

Archives are clonable:
	git clone --mirror https://yhbt.net/yahns-public
	git clone --mirror http://ou63pmih66umazou.onion/yahns-public

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.lang.ruby.yahns
	nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.yahns

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox