guix-commits
[Top][All Lists]
Advanced

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

[shepherd] 20/32: service: Allow 'running' value to be a thunk.


From: Ludovic Courtès
Subject: [shepherd] 20/32: service: Allow 'running' value to be a thunk.
Date: Wed, 30 Mar 2022 11:01:31 -0400 (EDT)

civodul pushed a commit to branch master
in repository shepherd.

commit 4963357393b24eb8ab26c606b72f65742d89a6c7
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sat Mar 26 10:28:21 2022 +0100

    service: Allow 'running' value to be a thunk.
    
    Constructors may now return a thunk whose return value changes over
    time.
    
    * modules/shepherd/service.scm (service-running-value): New procedure.
    (running?, start, action, stop, service->sexp, handle-SIGCHLD)
    (check-for-dead-services): Call it instead of accessing the 'running'
    slot directly.
---
 doc/shepherd.texi            |  3 ++-
 modules/shepherd/service.scm | 26 ++++++++++++++++----------
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 88e100a..7dfe8e3 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -641,7 +641,8 @@ be set to the return value of the procedure in the 
@code{start} slot.
 It will also be passed as an argument to the procedure in the
 @code{stop} slot.  If it is set a value that is an integer, it is
 assumed to be a process id, and shepherd will monitor the process for
-unexpected exits.  This slot can not be initialized with a keyword.
+unexpected exits.  If it is a procedure, that procedure is called to get
+at the underlying value.  This slot cannot be initialized with a keyword.
 
 @item
 @vindex respawn? (slot of <service>)
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index ef57282..97c0c59 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -292,9 +292,15 @@ wire."
 (define-method (canonical-name (obj <service>))
   (car (provided-by obj)))
 
+;; Return the "running value" of OBJ.
+(define-method (service-running-value (obj <service>))
+  (match (slot-ref obj 'running)
+    ((? procedure? proc) (proc))
+    (value value)))
+
 ;; Return whether the service is currently running.
 (define-method (running? (obj <service>))
-  (and (slot-ref obj 'running) #t))
+  (and (service-running-value obj) #t))
 
 ;; Return a list of all actions implemented by OBJ. 
 (define-method (action-list (obj <service>))
@@ -326,18 +332,18 @@ wire."
   (cond ((running? obj)
         (local-output (l10n "Service ~a is already running.")
                       (canonical-name obj))
-         (slot-ref obj 'running))
+         (service-running-value obj))
        ((not (enabled? obj))
         (local-output (l10n "Service ~a is currently disabled.")
                       (canonical-name obj))
-         (slot-ref obj 'running))
+         (service-running-value obj))
        ((let ((conflicts (conflicts-with-running obj)))
           (or (null? conflicts)
               (local-output (l10n "Service ~a conflicts with running services 
~a.")
                             (canonical-name obj)
                             (map canonical-name conflicts)))
           (not (null? conflicts)))
-        (slot-ref obj 'running))
+        (service-running-value obj))
        (else
         ;; It is not running and does not conflict with anything
         ;; that's running, so we can go on and launch it.
@@ -358,7 +364,7 @@ wire."
                                                              key args)))))
 
           ;; Status message.
-           (let ((running (slot-ref obj 'running)))
+           (let ((running (service-running-value obj)))
              (when (one-shot? obj)
                (slot-set! obj 'running #f))
              (local-output (if running
@@ -424,7 +430,7 @@ is not already running, and will return SERVICE's canonical 
name in a list."
                (catch #t
                  (lambda ()
                    (apply (slot-ref service 'stop)
-                          (slot-ref service 'running)
+                          (service-running-value service)
                           args))
                  (lambda (key . args)
                    ;; Special case: 'root' may quit.
@@ -497,7 +503,7 @@ is not already running, and will return SERVICE's canonical 
name in a list."
     ;; it provides generally useful functionality and information.
     (catch #t
       (lambda ()
-        (apply proc (slot-ref obj 'running) args))
+        (apply proc (service-running-value obj) args))
       (lambda (key . args)
         ;; Special case: 'root' may quit.
         (and (eq? root-service obj)
@@ -583,7 +589,7 @@ clients."
             ;; that whole thing is valid read syntax; we do not want things
             ;; like #<undefined> to be sent to the client.
             (enabled? ,(enabled? service))
-            (running ,(result->sexp (slot-ref service 'running)))
+            (running ,(result->sexp (service-running-value service)))
             (conflicts ,(map canonical-name (conflicts-with service)))
             (last-respawns ,(slot-ref service 'last-respawns))
             ,@(if (slot-ref service 'one-shot?)
@@ -1383,7 +1389,7 @@ otherwise by updating its state."
       ((pid . _)
        (let ((serv (find-service (lambda (serv)
                                    (and (enabled? serv)
-                                        (match (slot-ref serv 'running)
+                                        (match (service-running-value serv)
                                           ((? number? pid*)
                                            (= pid pid*))
                                           (_ #f)))))))
@@ -1577,7 +1583,7 @@ where prctl/PR_SET_CHILD_SUBREAPER is unsupported."
     (catch-system-error (kill pid 0) #t))
 
   (for-each-service (lambda (service)
-                      (let ((running (slot-ref service 'running)))
+                      (let ((running (service-running-value service)))
                         (when (and (integer? running)
                                    (not (process-exists? running)))
                           (local-output (l10n "PID ~a (~a) is dead!")



reply via email to

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