guix-commits
[Top][All Lists]
Advanced

[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"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]