[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
- [shepherd] branch wip-fibers created (now 69ea4bd), Ludovic Courtès, 2022/03/25
- [shepherd] 04/13: build: Capture the source and object directories of Fibers., Ludovic Courtès, 2022/03/25
- [shepherd] 09/13: service: 'make-forkexec-constructor' spawns a logging fiber., Ludovic Courtès, 2022/03/25
- [shepherd] 10/13: doc: Fix inetutils cross-reference., Ludovic Courtès, 2022/03/25
- [shepherd] 12/13: service: Add the #:transient? slot.,
Ludovic Courtès <=
- [shepherd] 01/13: shepherd: Factorize out the main loop., Ludovic Courtès, 2022/03/25
- [shepherd] 02/13: build: Drop support for Guile 2.0., Ludovic Courtès, 2022/03/25
- [shepherd] 03/13: Use Fibers., Ludovic Courtès, 2022/03/25
- [shepherd] 05/13: shepherd: Use one fiber for signal handling, and one for clients., Ludovic Courtès, 2022/03/25
- [shepherd] 06/13: service: 'read-pid-file' no longer blocks., Ludovic Courtès, 2022/03/25
- [shepherd] 07/13: service: 'read-pid-file' uses (@ (guile) sleep) when it's not suspendable., Ludovic Courtès, 2022/03/25
- [shepherd] 08/13: shepherd: Encode log as UTF-8 unconditionally., Ludovic Courtès, 2022/03/25
- [shepherd] 11/13: service: Remove unused 'make-init.d-service'., Ludovic Courtès, 2022/03/25
- [shepherd] 13/13: service: Add inetd constructor and destructor., Ludovic Courtès, 2022/03/25