unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] Shepherd: Add respawn-limit paramter to service class.
@ 2021-09-21  7:41 Ryan Sundberg
  2021-09-21 19:27 ` Joshua Branson
  0 siblings, 1 reply; 2+ messages in thread
From: Ryan Sundberg @ 2021-09-21  7:41 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 439 bytes --]

Hello Guix devs,

This patch to GNU Shepherd removes the hard-coded respawn limit and
makes it a configurable option.
The respawn limit works generally the same way as before, allowing N
respawns in M seconds:

#:respawn-limit '(N . M)

We can disable respawns by setting N to 0, which will abort the service
after the first crash. Likewise, we can always respawn by setting

#:respawn-limit #f


Sincerely,
Ryan Sundberg

[-- Attachment #2: 0001-service-Add-respawn-limit-paramter-to-the-service-cl.patch --]
[-- Type: text/x-patch, Size: 5938 bytes --]

From 94ad8057c6f9a020f12efd78d482b0cf4fe160ec Mon Sep 17 00:00:00 2001
From: Ryan Sundberg <ryan@arctype.co>
Date: Sun, 11 Jul 2021 13:54:04 -0700
Subject: [PATCH] service: Add respawn-limit paramter to the service class.

Makes respawn-limit a configurable parameter on service. In addition, we
allow the limit to be set to #f to indicate no respawn limit.

* modules/shepherd/service.scm: Add respawn-limit
---
 modules/shepherd/service.scm | 86 +++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 40 deletions(-)

diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index ad8608b..d741e0b 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -134,30 +134,6 @@
     ((_)
      '())))
 
-;; Respawning CAR times in CDR seconds will disable the service.
-;;
-;; XXX: The terrible hack in (shepherd) using SIGALRM to work around
-;; unreliable SIGCHLD delivery means that it might take up to 1 second for
-;; SIGCHLD to be delivered.  Thus, arrange for the car to be lower than the
-;; cdr.
-(define respawn-limit '(5 . 7))
-
-(define (respawn-limit-hit? respawns times seconds)
-  "Return true of RESPAWNS, the list of times at which a given service was
-respawned, shows that it has been respawned more than TIMES in SECONDS."
-  (define now (current-time))
-
-  ;; Note: This is O(TIMES), but TIMES is typically small.
-  (let loop ((times    times)
-             (respawns respawns))
-    (match respawns
-      (()
-       #f)
-      ((last-respawn rest ...)
-       (or (zero? times)
-           (and (> (+ last-respawn seconds) now)
-                (loop (- times 1) rest)))))))
-
 (define-class <service> ()
   ;; List of provided service-symbols.  The first one is also called
   ;; the `canonical name' and must be unique to this service.
@@ -221,7 +197,16 @@ respawned, shows that it has been respawned more than TIMES in SECONDS."
   (last-respawns #:init-form '())
   ;; A replacement for when this service is stopped.
   (replacement #:init-keyword #:replacement
-               #:init-value #f))
+               #:init-value #f)
+  ;; Respawning CAR times in CDR seconds will disable the service.
+  ;;
+  ;; Respawn limit (times, seconds). Set to #f to disable respawn limits.
+  ;; XXX: The terrible hack in (shepherd) using SIGALRM to work around
+  ;; unreliable SIGCHLD delivery means that it might take up to 1 second 
for
+  ;; SIGCHLD to be delivered.  Thus, arrange for the car to be lower than the
+  ;; cdr.
+  (respawn-limit #:init-keyword #:respawn-limit
+                 #:init-value '(5 . 7)))
 
 (define (service? obj)
   "Return true if OBJ is a service."
@@ -587,8 +572,6 @@ clients."
 (define-method (depends-resolved? (obj <service>))
   (every lookup-running (required-by obj)))
 
-\f
-
 (define (launch-service name proc args)
   "Try to start (with PROC) a service providing NAME; return #f on failure.
 Used by `start' and `enforce'."
@@ -648,8 +631,24 @@ results."
                (apply action service the-action args))
              which-services))))
 
-
-\f
+(define-method (respawn-limit-hit? (serv <service>))
+  "Return true if service SERV shows that it has been respawned more than it's
+respawn-limit TIMES in SECONDS. If the respawn-limit is #f, apply no limit."
+  (match (slot-ref serv 'respawn-limit)
+    (#f #f)
+    ((times . seconds)
+     (let* ((now (current-time))
+            (respawns (slot-ref serv 'last-respawns)))
+       ;; Note: This is O(TIMES), but TIMES is typically small.
+       (let loop ((times    times)
+                  (respawns respawns))
+         (match respawns
+           (()
+            #f)
+           ((last-respawn rest ...)
+            (or (zero? times)
+                (and (> (+ last-respawn seconds) now)
+                     (loop (- times 1) rest))))))))))
 
 ;; Handling of unprovided service-symbols.  This can be called in
 ;; either of the following ways (i.e. with either three or four
@@ -1140,18 +1139,25 @@ attempted to respawn the service a number of times already and it keeps dying,
 then disable it."
   (slot-set! serv 'running #f)
   (if (and (respawn? serv)
-           (not (respawn-limit-hit? (slot-ref serv 'last-respawns)
-                                    (car respawn-limit)
-                                    (cdr respawn-limit))))
+           (not (respawn-limit-hit? serv)))
       (if (not (slot-ref serv 'waiting-for-termination?))
-          (begin
-            ;; Everything is okay, start it.
-            (local-output (l10n "Respawning ~a.")
-                          (canonical-name serv))
-            (slot-set! serv 'last-respawns
-                       (cons (current-time)
-                             (slot-ref serv 'last-respawns)))
-            (start serv))
+          (match (slot-ref serv 'respawn-limit)
+            (#f
+             (begin
+               (local-output (l10n "Respawning ~a.")
+                             (canonical-name serv))
+               (start serv)))
+            ((respawn-limit-times . _)
+             (let ((last-respawns (slot-ref serv 'last-respawns)))
+               ;; Everything is okay, start it.
+               (local-output (l10n "Respawning ~a.")
+                             (canonical-name serv))
+               (slot-set! serv 'last-respawns
+                          (cons (current-time)
+                                ;; Only take the last n times here to prevent unbounded
+                                ;; list growth
+                                (take last-respawns (min (length last-respawns) respawn-limit-times))))
+               (start serv))))
           ;; We have just been waiting for the
           ;; termination.  The `running' slot has already
           ;; been set to `#f' by `stop'.
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Shepherd: Add respawn-limit paramter to service class.
  2021-09-21  7:41 [PATCH] Shepherd: Add respawn-limit paramter to service class Ryan Sundberg
@ 2021-09-21 19:27 ` Joshua Branson
  0 siblings, 0 replies; 2+ messages in thread
From: Joshua Branson @ 2021-09-21 19:27 UTC (permalink / raw)
  To: Ryan Sundberg; +Cc: guix-devel

Ryan Sundberg <ryan@arctype.co> writes:

> Hello Guix devs,
>
> This patch to GNU Shepherd removes the hard-coded respawn limit and
> makes it a configurable option.
> The respawn limit works generally the same way as before, allowing N
> respawns in M seconds:

You typically want to send patches to guix-patches@gnu.org.  :)

>
> #:respawn-limit '(N . M)
>
> We can disable respawns by setting N to 0, which will abort the service
> after the first crash. Likewise, we can always respawn by setting
>
> #:respawn-limit #f
>
> Sincerely,
> Ryan Sundberg
>
>

-- 
Joshua Branson (jab in #guix)
Sent from Emacs and Gnus
  https://gnucode.me
  https://video.hardlimit.com/accounts/joshua_branson/video-channels
  https://propernaming.org
  "You can have whatever you want, as long as you help
enough other people get what they want." - Zig Ziglar
  


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-09-21 19:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-21  7:41 [PATCH] Shepherd: Add respawn-limit paramter to service class Ryan Sundberg
2021-09-21 19:27 ` Joshua Branson

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).