Subject: bug#77274: closed (Re: bug#77274: [Shepherd] Competing one-shot service starter gets erroneous failure)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 26 Mar 2025 11:37:02 +0000

Your bug report

#77274: [Shepherd] Competing one-shot service starter gets erroneous failure

which was filed against the guix package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
77274: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77274
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#77274: [Shepherd] Competing one-shot service starter gets erroneous failure
From: Ludovic Courtès <[email-masked]>
To: [email-masked]
Date: Wed, 26 Mar 2025 12:36:17 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Ludovic Courtès <[email-masked]> skribis:

> As of 1.0.3, when two clients start the same one-shot service, the one
> that loses the race never sees the value that was produced by the
> ‘start’ method.
>
>   herd start one-shot & herd start one-shot
>
> Here one of the ‘herd start’ processes will wrongfully fail with “failed
> to start service one-shot”.
>
> Instead, it calls ‘service-running-value’ but that always returns #f
> because the one-shot service was stopped in the meantime.  I’m referring
> to this bit of ‘start-service’:
>
>       (match (get-message reply)
>         (#f
>          ;; We lost the race: SERVICE is already running.
>          (service-running-value service))   ;<- here
>         …)

Fixed in f730106fe1cf9a3efc2f327cc5716335585ac92b.

Ludo'.

Subject: [Shepherd] Competing one-shot service starter gets erroneous failure
From: Ludovic Courtès <[email-masked]>
To: [email-masked]
Date: Wed, 26 Mar 2025 11:14:24 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

As of 1.0.3, when two clients start the same one-shot service, the one
that loses the race never sees the value that was produced by the
‘start’ method.

  herd start one-shot & herd start one-shot

Here one of the ‘herd start’ processes will wrongfully fail with “failed
to start service one-shot”.

Instead, it calls ‘service-running-value’ but that always returns #f
because the one-shot service was stopped in the meantime.  I’m referring
to this bit of ‘start-service’:

      (match (get-message reply)
        (#f
         ;; We lost the race: SERVICE is already running.
         (service-running-value service))   ;<- here
        …)

Attached is a reproducer.

Ludo’.

diff --git a/tests/one-shot.sh b/tests/one-shot.sh
index eeecea7..491eeae 100644
--- a/tests/one-shot.sh
+++ b/tests/one-shot.sh
@@ -1,5 +1,5 @@
 # GNU Shepherd --- Test one-shot services.
-# Copyright © 2019, 2023-2024 Ludovic Courtès <[email-masked]>
+# Copyright © 2019, 2023-2025 Ludovic Courtès <[email-masked]>
 #
 # This file is part of the GNU Shepherd.
 #
@@ -197,4 +197,35 @@ test "$(cat "$stamp")" = "third"
 $herd start fourth && false
 $herd start fourth && false
 
+# Check the behavior of two clients competing to start the same one-shot
+# service.  Both should succeed.
+
+cat > "$conf" <<EOF
+(register-services
+  (list (service
+          '(fifth)
+          #:one-shot? #t
+          #:start (lambda ()
+                    (let loop ()
+                      (unless (file-exists? "$stamp")
+                        (sleep 0.5)
+                        (loop)))
+                    #t))))
+EOF
+
+$herd load root "$conf"
+
+rm -f "$stamp"
+
+$herd start fifth &
+herd_start_pid1=$!
+$herd start fifth &
+herd_start_pid2=$!
+until $herd status fifth | grep starting; do sleep 0.5; done
+touch "$stamp"			# trigger starting->running transition
+
+# Both 'herd start' processes should have succeeded.
+wait $herd_start_pid1
+wait $herd_start_pid2
+
 $herd stop root