From patchwork Tue Sep 21 07:42:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Sundberg X-Patchwork-Id: 33229 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 4B08927BBE3; Tue, 21 Sep 2021 08:45:07 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,T_DKIM_INVALID, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id B902427BBE1 for ; Tue, 21 Sep 2021 08:45:06 +0100 (BST) Received: from localhost ([::1]:39144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mSaSf-0005EF-QN for patchwork@mira.cbaines.net; Tue, 21 Sep 2021 03:45:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60738) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSaQf-0002cv-WA for guix-patches@gnu.org; Tue, 21 Sep 2021 03:43:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:33210) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mSaQf-0001zd-PH for guix-patches@gnu.org; Tue, 21 Sep 2021 03:43:01 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mSaQf-0005VC-Nq for guix-patches@gnu.org; Tue, 21 Sep 2021 03:43:01 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#50717] [PATCH] Shepherd: Add respawn-limit paramter to service class. Resent-From: Ryan Sundberg Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 21 Sep 2021 07:43:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 50717 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 50717@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.163221013921089 (code B ref -1); Tue, 21 Sep 2021 07:43:01 +0000 Received: (at submit) by debbugs.gnu.org; 21 Sep 2021 07:42:19 +0000 Received: from localhost ([127.0.0.1]:44756 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mSaPy-0005U4-Uc for submit@debbugs.gnu.org; Tue, 21 Sep 2021 03:42:19 -0400 Received: from lists.gnu.org ([209.51.188.17]:36726) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mSaPx-0005Tv-Lm for submit@debbugs.gnu.org; Tue, 21 Sep 2021 03:42:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60588) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSaPx-0001H1-AN for guix-patches@gnu.org; Tue, 21 Sep 2021 03:42:17 -0400 Received: from mail.arctype.co ([138.68.9.245]:36307) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mSaPv-0001Kr-BN for guix-patches@gnu.org; Tue, 21 Sep 2021 03:42:17 -0400 Received: from authenticated-user (mail.arctype.co [138.68.9.245]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by mail.arctype.co (Postfix) with ESMTPSA id 4898E13B228 for ; Tue, 21 Sep 2021 07:42:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=arctype.co; s=mail; t=1632210134; bh=IYe4WbCIEWLswRwoBw4WT1XBRSJLxIoFOS9Vy3TFBto=; h=From:Subject:To:Date:From; b=eqoyOVcv9RWwYtDHJ9tFDQnHgAQfB8omPz0pxTWdbjn26dlwob/HNPTrnMcsDv510 6BXJCyLslkc37RXSDNibazJwOg8OwjBub4g3T/Boq/6rww/wHDRk5AWKshpPC1nRXA IsXSIk3cs39EwljpNQVE66HlcE0KCSIsI+7CjV2jsYaZ/jgDUIqqMmFBgj8yiIGcFY H9UFY49R4qP4Akdu1ijfMw5io4aoJ9YCsdhSC8I0Bvk5DJEfGC2VVWJfK9D3As+lQr bR4c+uRG2uPlS61l5fISmOdZ7xnvoSSpEe4e5+vtdYtKg1PUJdAwOX+3XC6kOpFQeI gH58NgDzq2Ozg== Message-ID: Date: Tue, 21 Sep 2021 00:42:14 -0700 MIME-Version: 1.0 Received-SPF: pass client-ip=138.68.9.245; envelope-from=ryan@arctype.co; helo=mail.arctype.co X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" Reply-to: Ryan Sundberg X-ACL-Warn: , Ryan Sundberg via Guix-patches X-Patchwork-Original-From: Ryan Sundberg via Guix-patches via From: Ryan Sundberg X-getmail-retrieved-from-mailbox: Patches 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 From 94ad8057c6f9a020f12efd78d482b0cf4fe160ec Mon Sep 17 00:00:00 2001 From: Ryan Sundberg 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 () ;; 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 )) (every lookup-running (required-by obj))) - - (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)))) - - +(define-method (respawn-limit-hit? (serv )) + "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