guix-commits
[Top][All Lists]
Advanced

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

[shepherd] 03/04: service: Thread 'enabled?' boolean in service controll


From: Ludovic Courtès
Subject: [shepherd] 03/04: service: Thread 'enabled?' boolean in service controller fiber.
Date: Sun, 5 Mar 2023 16:15:55 -0500 (EST)

civodul pushed a commit to branch master
in repository shepherd.

commit 38d9e132e744de580da14faa0016863bb48a0a98
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sun Mar 5 21:46:50 2023 +0100

    service: Thread 'enabled?' boolean in service controller fiber.
    
    * modules/shepherd/service.scm (<service>)[enabled?]: Remove.
    (service-controller): Thread 'enabled?' through the loop.  Add clauses
    for 'enabled?', 'enable', and 'disable'.
    (service-enabled?, enable-service, disable-service): New procedures.
    (enabled?): New method.
    (enable): Call 'enable-service' instead of changing the 'enabled?' slot.
    (disable): Likewise.
    (start, service->sexp, process-monitor): Use 'service-enabled?' instead
    of 'enabled?'.
    (respawn-service): Call 'disable-service' instead of changing the
    'enabled?' slot.
---
 doc/shepherd.texi            |  8 -----
 modules/shepherd/service.scm | 74 ++++++++++++++++++++++++++++----------------
 2 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index db64b9e..a7c10d3 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -726,14 +726,6 @@ on a service when it is running.  A typical example for 
this is the
 Convenience} is provided to abstract the actual data representation
 format for this slot.  (It actually is a hash currently.)
 
-@item
-@vindex enabled? (slot of <service>)
-@code{enabled?} cannot be initialized with a keyword, and contains
-@code{#t} by default.  When the value becomes @code{#f} at some point,
-this will prevent the service from getting started.  A service can be
-enabled and disabled with the methods @code{enable} and
-@code{disable}, respectively @ref{Methods of services}.
-
 @item
 @vindex replacement (slot of <service>)
 @code{replacement} specifies a service to be used to replace this one
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index 8d65b87..ca039e9 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -267,10 +267,6 @@ Log abnormal termination reported by @var{status}."
   ;; A description of the service.
   (docstring #:init-keyword #:docstring
             #:init-value "[No description].")
-  ;; A service can be disabled if it is respawning too fast; it is
-  ;; also possible to enable or disable it manually.
-  (enabled? #:init-value #t
-           #:getter enabled?)
   ;; A replacement for when this service is stopped.
   (replacement #:init-keyword #:replacement
                #:init-value #f)
@@ -308,17 +304,26 @@ Log abnormal termination reported by @var{status}."
   (let loop ((status 'stopped)
              (value #f)
              (condition #f)
+             (enabled? #t)
              (respawns '()))
     (match (get-message channel)
       (('running reply)
        (put-message reply value)
-       (loop status value condition respawns))
+       (loop status value condition enabled? respawns))
       (('status reply)
        (put-message reply status)
-       (loop status value condition respawns))
+       (loop status value condition enabled? respawns))
+      (('enabled? reply)
+       (put-message reply enabled?)
+       (loop status value condition enabled? respawns))
       (('respawn-times reply)
        (put-message reply respawns)
-       (loop status value condition respawns))
+       (loop status value condition enabled? respawns))
+
+      ('enable                                    ;no reply
+       (loop status value condition #t respawns))
+      ('disable                                   ;no reply
+       (loop status value condition #f respawns))
 
       (('start reply)
        ;; Attempt to start SERVICE, blocking if it is already being started.
@@ -328,7 +333,7 @@ Log abnormal termination reported by @var{status}."
        (cond ((eq? 'running status)
               ;; SERVICE is already running: send #f on REPLY.
               (put-message reply #f)
-              (loop status value condition respawns))
+              (loop status value condition enabled? respawns))
              ((eq? 'starting status)
               ;; SERVICE is being started: wait until it has started and
               ;; then send #f on REPLY.
@@ -336,7 +341,7 @@ Log abnormal termination reported by @var{status}."
                (lambda ()
                  (wait condition)
                  (put-message reply #f)))
-              (loop status value condition respawns))
+              (loop status value condition enabled? respawns))
              (else
               ;; Become the one that starts SERVICE.
               (let ((condition (make-condition))
@@ -351,7 +356,7 @@ Log abnormal termination reported by @var{status}."
                 (local-output (l10n "Starting service ~a...")
                               (canonical-name service))
                 (put-message reply notification)
-                (loop 'starting value condition respawns)))))
+                (loop 'starting value condition enabled? respawns)))))
       (((? started-message?) value)               ;no reply
        (local-output (l10n "Service ~a running with value ~s.")
                      (canonical-name service) value)
@@ -361,6 +366,7 @@ Log abnormal termination reported by @var{status}."
                  'stopped)
              (and (not (one-shot? service)) value)
              #f
+             enabled?
              respawns))
 
       (('stop reply)
@@ -375,11 +381,11 @@ Log abnormal termination reported by @var{status}."
                (lambda ()
                  (wait condition)
                  (put-message reply #f)))
-              (loop status value condition respawns))
+              (loop status value condition enabled? respawns))
              ((not (eq? status 'running))
               ;; SERVICE is not running: send #f on REPLY.
               (put-message reply #f)
-              (loop status value condition respawns))
+              (loop status value condition enabled? respawns))
              (else
               ;; Become the one that stops SERVICE.
               (let ((condition (make-condition))
@@ -396,21 +402,21 @@ Log abnormal termination reported by @var{status}."
                 (local-output (l10n "Stopping service ~a...")
                               (canonical-name service))
                 (put-message reply notification)
-                (loop 'stopping value condition respawns)))))
+                (loop 'stopping value condition enabled?  respawns)))))
       ((? stopped-message?)                       ;no reply
        (local-output (l10n "Service ~a is now stopped.")
                      (canonical-name service))
        (signal-condition! condition)
-       (loop 'stopped #f #f '()))
+       (loop 'stopped #f #f enabled? '()))
 
       ('notify-termination                        ;no reply
-       (loop 'stopped #f condition respawns))
+       (loop 'stopped #f condition enabled? respawns))
 
       (('handle-termination exit-status)          ;no reply
        ;; Handle premature termination of this service's process, possibly by
        ;; respawning it, unless STATUS is 'stopping'.
        (if (eq? status 'stopping)
-           (loop status value condition respawns)
+           (loop status value condition enabled? respawns)
            (begin
              (spawn-fiber
               (lambda ()
@@ -418,10 +424,10 @@ Log abnormal termination reported by @var{status}."
                  ((slot-ref service 'handle-termination)
                   service value exit-status))
                 (put-message channel 'notify-termination)))
-             (loop 'stopped #f #f respawns))))
+             (loop 'stopped #f #f enabled? respawns))))
 
       ('record-respawn-time                       ;no reply
-       (loop status value condition
+       (loop status value condition enabled?
              (cons (current-time) respawns)))
 
       (('replace-if-running replacement reply)
@@ -431,10 +437,10 @@ Log abnormal termination reported by @var{status}."
                            (canonical-name service))
              (slot-set! service 'replacement replacement)
              (put-message reply #t)
-             (loop status value condition respawns))
+             (loop status value condition enabled? respawns))
            (begin
              (put-message reply #f)
-             (loop status value condition respawns)))))))
+             (loop status value condition enabled? respawns)))))))
 
 (define (service? obj)
   "Return true if OBJ is a service."
@@ -521,6 +527,18 @@ channel and wait for its reply."
   ;; Return the list of respawn times of @var{service}.
   (service-control-message 'respawn-times))
 
+(define service-enabled?
+  ;; Return true if @var{service} is enabled, false otherwise.
+  (service-control-message 'enabled?))
+
+(define (enable-service service)
+  "Enable @var{service}."
+  (put-message (service-control service) 'enable))
+
+(define (disable-service service)
+  "Disable @var{service}."
+  (put-message (service-control service) 'disable))
+
 (define (record-service-respawn-time service)
   "Record the current time as the last respawn time for @var{service}."
   (put-message (service-control service) 'record-respawn-time))
@@ -548,14 +566,18 @@ channel and wait for its reply."
 (define-method (defines-action? (obj <service>) action)
   (and (lookup-action obj action) #t))
 
+(define-method (enabled? (service <service>))
+  "Return true if @var{service} is enabled."
+  (service-enabled? service))
+
 ;; Enable the service, allow it to get started.
 (define-method (enable (obj <service>))
-  (slot-set! obj 'enabled? #t)
+  (enable-service obj)
   (local-output (l10n "Enabled service ~a.") (canonical-name obj)))
 
 ;; Disable the service, make it unstartable.
 (define-method (disable (obj <service>))
-  (slot-set! obj 'enabled? #f)
+  (disable-service obj)
   (local-output (l10n "Disabled service ~a.") (canonical-name obj)))
 
 (define (start-in-parallel services)
@@ -585,7 +607,7 @@ that could not be started."
         (local-output (l10n "Service ~a is already running.")
                       (canonical-name obj))
          (service-running-value obj))
-       ((not (enabled? obj))
+       ((not (service-enabled? obj))
         (local-output (l10n "Service ~a is currently disabled.")
                       (canonical-name obj))
          (service-running-value obj))
@@ -853,7 +875,7 @@ clients."
             ;; Status.  Use 'result->sexp' for the running value to make sure
             ;; that whole thing is valid read syntax; we do not want things
             ;; like #<undefined> to be sent to the client.
-            (enabled? ,(enabled? service))
+            (enabled? ,(service-enabled? service))
             (running ,(result->sexp (service-running-value service)))
             (conflicts ,(map canonical-name (conflicts-with service)))
             (last-respawns ,(service-respawn-times service))
@@ -2135,7 +2157,7 @@ otherwise by updating its state."
       (('handle-process-termination pid status)
        ;; Handle the termination of PID.
        (match (find-service (lambda (serv)
-                              (and (enabled? serv)
+                              (and (service-enabled? serv)
                                    (match (service-running-value serv)
                                      ((? number? pid*)
                                       (= pid pid*))
@@ -2323,7 +2345,7 @@ then disable it."
                       (canonical-name serv))
         (when (respawn? serv)
           (local-output (l10n "  (Respawning too fast.)")))
-        (slot-set! serv 'enabled? #f)
+        (disable-service serv)
 
         (when (transient? serv)
           (put-message (current-registry-channel) `(unregister (,serv)))



reply via email to

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