[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[shepherd] 02/03: service: Wait when attempting to stop a service in "st
From: |
Ludovic Courtès |
Subject: |
[shepherd] 02/03: service: Wait when attempting to stop a service in "starting" state. |
Date: |
Sat, 29 Apr 2023 13:12:55 -0400 (EDT) |
civodul pushed a commit to branch master
in repository shepherd.
commit 347d274e945334cbc0247512da84ccb9efcad0ff
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sat Apr 29 01:31:23 2023 +0200
service: Wait when attempting to stop a service in "starting" state.
Previously, stopping a service would fail with "Service ~a might have
failed to stop." if it was in 'starting' state. Now it will wait until
the service is running before attempting to stop it.
* modules/shepherd/service.scm (service-controller): In 'stop' clause,
when STATUS is 'starting, wait CONDITION then resend message to
CHANNEL. Send #f on REPLY only if STATUS is 'stopped.
* tests/stopping-status.sh: Test it.
---
modules/shepherd/service.scm | 14 ++++++++++++--
tests/starting-status.sh | 33 +++++++++++++++++++++++++++++++--
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index c8c1335..498396a 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -519,10 +519,20 @@ denoting what the service provides."
(wait condition)
(put-message reply #f)))
(loop))
- ((not (eq? status 'running))
- ;; SERVICE is not running: send #f on REPLY.
+ ((eq? status 'stopped)
+ ;; SERVICE is stopped: send #f on REPLY.
(put-message reply #f)
(loop))
+ ((eq? 'starting status)
+ ;; SERVICE is being started: wait until it is started, then try
+ ;; stopping it again.
+ (spawn-fiber
+ (lambda ()
+ (local-output (l10n "Waiting for ~a to start...")
+ (service-canonical-name service))
+ (wait condition)
+ (put-message channel `(stop ,reply))))
+ (loop))
(else
;; Become the one that stops SERVICE.
(let ((notification (make-channel)))
diff --git a/tests/starting-status.sh b/tests/starting-status.sh
index e90aed6..bcd08b2 100644
--- a/tests/starting-status.sh
+++ b/tests/starting-status.sh
@@ -101,10 +101,39 @@ done
$herd stop test
! test -f "$stamp"
+test $(grep "Starting service test" "$log" | wc -l) = 1
+
+# Now, once 'test' is stopped, start it. While it is being started, attempt
+# to stop it: this should do nothing until it has started. Cause it to start,
+# and check that the 'herd start' and 'herd stop' processes have completed,
+# and that it has stopped.
+
+echo "Now trying to stop a service in 'starting' state."
+$herd start test &
+herd_start_pid=$!
+
+$herd stop test &
+herd_stop_pid1=$!
+$herd stop test &
+herd_stop_pid2=$!
+
+for i in $(seq 1 3)
+do
+ $herd status test | grep "starting"
+ sleep 0.3
+done
+
+grep "Waiting for test to start" "$log"
+
+touch "$stamp" # trigger starting->running transition
+while kill -0 $herd_start_pid; do sleep 0.5; done
+while kill -0 $herd_stop_pid1; do sleep 0.5; done
+while kill -0 $herd_stop_pid2; do sleep 0.5; done
+$herd status test | grep stopped
+
+
$herd stop root
! kill -0 $shepherd_pid
-test $(grep "Starting service test" "$log" | wc -l) = 1
-
rm -rf "$confdir"
rm -rf "$datadir"