guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[shepherd] 12/13: service: Add the #:transient? slot.


From: Ludovic Courtès
Subject: [shepherd] 12/13: service: Add the #:transient? slot.
Date: Fri, 25 Mar 2022 17:59:01 -0400 (EDT)

civodul pushed a commit to branch wip-fibers
in repository shepherd.

commit 894983c5ad5dd78f40629e16f015f5a467194c41
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Fri Mar 25 14:45:54 2022 +0100

    service: Add the #:transient? slot.
    
    * modules/shepherd/service.scm (<service>)[transient?]: New slot.
    (stop, respawn-service): Unregister transient services.
    * tests/transient.sh: New file.
    * Makefile.am (TESTS): Add it.
    * doc/shepherd.texi (Slots of services): Document it.
---
 Makefile.am                  |  1 +
 doc/shepherd.texi            | 11 ++++++++
 modules/shepherd/service.scm | 19 ++++++++++++-
 tests/transient.sh           | 65 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 1564156..8f28a29 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -229,6 +229,7 @@ TESTS =                                             \
   tests/status-sexp.sh                         \
   tests/forking-service.sh                     \
   tests/one-shot.sh                            \
+  tests/transient.sh                           \
   tests/signals.sh
 
 TEST_EXTENSIONS = .sh
diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index bcd87dd..67f4c0e 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -665,6 +665,17 @@ initialization action.
 As for other services, the @code{start} method of a one-shot service must
 return a truth value to indicate success, and false to indicate failure.
 
+@item
+@vindex transient? (slot of <service>)
+@cindex transient services
+The @code{transient?} slot determines whether the service is a
+@dfn{transient service}.  A transient service is automatically
+unregistered when it terminates, be it because its @code{stop} method is
+called or because its associated process terminates.
+
+This is useful in the uncommon case of synthesized services that may not
+be restarted once they have completed.
+
 @item
 @vindex start (slot of <service>)
 @cindex Starting a service
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index e21e6bb..218e6e0 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -47,6 +47,7 @@
             canonical-name
             running?
             one-shot?
+            transient?
             action-list
             lookup-action
             defines-action?
@@ -175,6 +176,11 @@ respawned, shows that it has been respawned more than 
TIMES in SECONDS."
   (one-shot? #:init-keyword #:one-shot?
              #:init-value #f
              #:getter one-shot?)
+  ;; If true, the service is "transient": it is unregistered as soon as it
+  ;; terminates, unless it is respawned.
+  (transient? #:init-keyword #:transient?
+              #:init-value #f
+              #:getter transient?)
   ;; If `#t', then assume the `running' slot specifies a PID and
   ;; respawn it if that process terminates.  Otherwise `#f'.
   (respawn? #:init-keyword #:respawn?
@@ -442,6 +448,12 @@ is not already running, and will return SERVICE's 
canonical name in a list."
                                  name)
                    (local-output (l10n "Service ~a has been stopped.")
                                  name))
+
+               (when (transient? service)
+                 (hashq-remove! %services (canonical-name service))
+                 (local-output (l10n "Transient service ~a unregistered.")
+                               (canonical-name service)))
+
                (cons name stopped-dependents)))))))
 
 ;; Call action THE-ACTION with ARGS.
@@ -1242,7 +1254,12 @@ then disable it."
                       (canonical-name serv))
         (when (respawn? serv)
           (local-output (l10n "  (Respawning too fast.)")))
-        (slot-set! serv 'enabled? #f))))
+        (slot-set! serv 'enabled? #f)
+
+        (when (transient? serv)
+          (hashq-remove! %services (canonical-name serv))
+          (local-output (l10n "Transient service ~a terminated, now 
unregistered.")
+                        (canonical-name serv))))))
 
 ;; Add NEW-SERVICES to the list of known services.
 (define (register-services . new-services)
diff --git a/tests/transient.sh b/tests/transient.sh
new file mode 100644
index 0000000..bf04278
--- /dev/null
+++ b/tests/transient.sh
@@ -0,0 +1,65 @@
+# GNU Shepherd --- Test transient services.
+# Copyright © 2022 Ludovic Courtès <ludo@gnu.org>
+#
+# This file is part of the GNU Shepherd.
+#
+# The GNU Shepherd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# The GNU Shepherd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the GNU Shepherd.  If not, see <http://www.gnu.org/licenses/>.
+
+shepherd --version
+herd --version
+
+socket="t-socket-$$"
+conf="t-conf-$$"
+log="t-log-$$"
+pid="t-pid-$$"
+
+herd="herd -s $socket"
+
+trap "cat $log || true; rm -f $socket $conf $log;
+      test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT
+
+cat > "$conf"<<EOF
+(register-services
+ (make <service>
+   #:provides '(transient-test1)
+   #:start (make-forkexec-constructor '("sleep" "600"))
+   #:transient? #t)
+ (make <service>
+   #:provides '(transient-test2)
+   #:start (make-forkexec-constructor '("sleep" "600"))
+   #:transient? #t))
+EOF
+
+rm -f "$pid"
+shepherd -I -s "$socket" -c "$conf" -l "$log" --pid="$pid" &
+
+# Wait till it's ready.
+while ! test -f "$pid" ; do sleep 0.3 ; done
+
+shepherd_pid="`cat $pid`"
+
+$herd start transient-test1
+$herd start transient-test2
+
+# Stop the service and make sure it gets unregistered.
+$herd status transient-test1 | grep started
+$herd stop transient-test1
+! $herd status transient-test1
+
+# Terminate the service and make sure it gets unregistered.
+$herd status transient-test2 | grep started
+kill $($herd status transient-test2 | grep Running | sed -e's/^.* 
\([0-9]\+\).*$/\1/g')
+! $herd status transient-test2
+
+test $($herd status | grep transient-test | wc -l) -eq 0



reply via email to

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