[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[shepherd] 02/02: service: Add ‘respawn-delay’ slot to <service>.
From: |
Ludovic Courtès |
Subject: |
[shepherd] 02/02: service: Add ‘respawn-delay’ slot to <service>. |
Date: |
Thu, 23 Nov 2023 17:25:13 -0500 (EST) |
civodul pushed a commit to branch master
in repository shepherd.
commit 1d3643f2576aff1869bba084c92684c81689a0a1
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Thu Nov 23 23:09:26 2023 +0100
service: Add ‘respawn-delay’ slot to <service>.
Fixes <https://issues.guix.gnu.org/64665>.
Suggested by Attila Lendvai <attila@lendvai.name>
and Felix Lechner <felix.lechner@lease-up.com>.
* modules/shepherd/service.scm (default-respawn-delay): New variable.
(<service>)[respawn-delay]: New slot.
(service): Add #:respawn-delay and honor it.
(service->sexp): Add ‘respawn-delay’.
(respawn-service): Add ‘sleep’ call.
* tests/status-sexp.sh: Call ‘default-respawn-delay’ in config file.
Update expected sexps.
* tests/systemd.sh: Pass #:respawn-delay 0.
* doc/shepherd.texi (Defining Services): Document #:respawn-delay.
(Service De- and Constructors): Document ‘default-respawn-delay’.
* NEWS: Update.
---
NEWS | 7 +++++++
doc/shepherd.texi | 19 +++++++++++++++++++
modules/shepherd/service.scm | 17 +++++++++++++++--
tests/status-sexp.sh | 14 ++++++++++----
tests/systemd.sh | 1 +
5 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/NEWS b/NEWS
index c0eb647..67b2901 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,13 @@ Please send Shepherd bug reports to bug-guix@gnu.org.
* Changes in 0.10.3
+** New #:respawn-delay parameter to ‘service’
+ (<https://issues.guix.gnu.org/64665>)
+
+This specifies a delay before a service is respawned. Its default value is
+given by ‘default-respawn-delay’ and defaults to 100ms. Until now, services
+were respawned immediately.
+
** Non-blocking ‘sleep’ replacement provided
Until now, user code could call (@ (guile) sleep), the core Guile binding for
diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 6f949fa..aca3a57 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -721,6 +721,13 @@ There is a limit to avoid endless respawning: when the
service gets
respawned ``too fast'', it is @dfn{disabled}---see
@code{#:respawn-limit} below.
+@cindex respawn delay
+@item #:respawn-delay
+Specify the delay before a service is respawned, in seconds (including a
+fraction), for services marked with @code{#:respawn? #t}. Its default
+value is @code{(default-respawn-delay)} (@pxref{Service De- and
+Constructors}).
+
@cindex respawn limit
@item #:respawn-limit
Specify the limit that prevents @command{shepherd} from respawning too
@@ -870,6 +877,11 @@ Return true if @var{service} is meant to be respawned if
its associated
process terminates prematurely.
@end deffn
+@deffn {Procedure} service-respawn-delay @var{service}
+Return the respawn delay of @var{service}, in seconds (an integer or a
+fraction or inexact number). See @code{#:respawn-delay} above.
+@end deffn
+
@deffn {Procedure} service-respawn-limit @var{service}
Return the respawn limit of @var{service}, expressed as a pair---see
@code{#:respawn-limit} above.
@@ -1154,6 +1166,13 @@ sent @code{SIGKILL} for immediate termination. It
defaults to 5
seconds.
@end defvar
+@cindex respawn delay
+@defvar default-respawn-delay
+This parameter specifies the default value of the @code{#:respawn-delay}
+parameter of @code{service} (@pxref{Defining Services}). It defaults to
+@code{0.1}, meaning a 100ms delay before respawning a service.
+@end defvar
+
@cindex respawn limit
@cindex disabled service
@defvar default-respawn-limit
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index 16f5868..c3bdf44 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -98,6 +98,7 @@
unregister-services
default-respawn-limit
+ default-respawn-delay
default-service-termination-handler
default-environment-variables
make-forkexec-constructor
@@ -211,6 +212,10 @@
use 'actions' instead.")
(actions rest ...)))
+(define default-respawn-delay
+ ;; Delay in seconds (exact or inexact) before respawning a service.
+ (make-parameter 0.1))
+
(define default-respawn-limit
;; Respawning CAR times in CDR seconds will disable the service.
;;
@@ -289,6 +294,10 @@ Log abnormal termination reported by @var{status}."
(respawn-limit #:init-keyword #:respawn-limit
#:init-thunk default-respawn-limit
#:getter service-respawn-limit)
+ ;; Delay in seconds before respawning a service.
+ (respawn-delay #:init-keyword #:respawn-delay
+ #:init-thunk default-respawn-delay
+ #:getter service-respawn-delay)
;; The action to perform to start the service. This must be a
;; procedure and may take an arbitrary amount of arguments, but it
;; must be possible to call it without any argument. If the
@@ -334,6 +343,7 @@ Log abnormal termination reported by @var{status}."
(transient? #f)
(respawn? #f)
(respawn-limit (default-respawn-limit))
+ (respawn-delay (default-respawn-delay))
(start (lambda () #t))
(stop (lambda (running) #f))
(actions (actions))
@@ -350,6 +360,7 @@ denoting what the service provides."
#:transient? transient?
#:respawn? respawn?
#:respawn-limit respawn-limit
+ #:respawn-delay respawn-delay
#:start start
#:stop stop
#:actions actions
@@ -1060,7 +1071,8 @@ clients."
(status ,(service-status service))
(one-shot? ,(one-shot-service? service))
(transient? ,(transient-service? service))
- (respawn-limit ,(service-respawn-limit service))))
+ (respawn-limit ,(service-respawn-limit service))
+ (respawn-delay ,(service-respawn-delay service))))
;;;
@@ -2543,7 +2555,8 @@ then disable it."
(car respawn-limit)
(cdr respawn-limit))))
(begin
- ;; Everything is okay, start it.
+ ;; Everything is okay, wait for a bit and restart it.
+ (sleep (service-respawn-delay serv))
(local-output (l10n "Respawning ~a.")
(service-canonical-name serv))
(record-service-respawn-time serv)
diff --git a/tests/status-sexp.sh b/tests/status-sexp.sh
index f35c23b..7c6ad1c 100644
--- a/tests/status-sexp.sh
+++ b/tests/status-sexp.sh
@@ -30,6 +30,8 @@ trap "rm -f $socket $conf $stamp $log;
test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT
cat > "$conf"<<EOF
+(default-respawn-delay 1)
+
(register-services
(list (service
'(foo)
@@ -78,7 +80,8 @@ root_service_sexp="
(status running)
(one-shot? #f)
(transient? #f)
- (respawn-limit (5 . 7)))"
+ (respawn-limit (5 . 7))
+ (respawn-delay 0.1))"
# Define a helper procedure that resets timestamps in the 'status-changes'
# property to make it easier to compare them.
@@ -117,7 +120,8 @@ $define_reset_timestamps
(status-changes ((running . 0) (starting . 0)))
(startup-failures ())
(status running)
- (one-shot? #f) (transient? #f) (respawn-limit (5 . 7)))
+ (one-shot? #f) (transient? #f)
+ (respawn-limit (5 . 7)) (respawn-delay 1))
(service (version 0)
(provides (bar)) (requires (foo))
(respawn? #f) (docstring \"Bar!\")
@@ -126,7 +130,8 @@ $define_reset_timestamps
(status-changes ())
(startup-failures ())
(status stopped)
- (one-shot? #f) (transient? #f) (respawn-limit (5 . 7))))))))
+ (one-shot? #f) (transient? #f)
+ (respawn-limit (5 . 7)) (respawn-delay 1)))))))
"
# The 'start' command should return the service sexp on success.
@@ -153,7 +158,8 @@ $define_reset_timestamps
(status-changes ((running . 0) (starting . 0)))
(startup-failures ())
(status running)
- (one-shot? #f) (transient? #f) (respawn-limit (5 . 7)))))))
+ (one-shot? #f) (transient? #f)
+ (respawn-limit (5 . 7)) (respawn-delay 1))))))
"
# Make sure we get an 'error' sexp when querying a nonexistent service.
diff --git a/tests/systemd.sh b/tests/systemd.sh
index 72c8ee1..90e81f5 100644
--- a/tests/systemd.sh
+++ b/tests/systemd.sh
@@ -63,6 +63,7 @@ cat > "$conf" <<EOF
'(test-systemd-unix)
#:start (make-systemd-constructor %command %endpoints)
#:stop (make-systemd-destructor)
+ #:respawn-delay 0 ;make the test slightly faster
#:respawn? #t)
(service
'(test-systemd-unix-eager)