Browse code

Merge pull request #52077 from thaJeztah/notify_readier

daemon: send systemd READY=1 after API serve loops start

Sebastiaan van Stijn authored on 2026/02/23 22:05:02
Showing 1 changed files
... ...
@@ -353,22 +353,22 @@ func (cli *daemonCLI) start(ctx context.Context) (retErr error) {
353 353
 
354 354
 	cli.setupConfigReloadTrap()
355 355
 
356
-	// after the daemon is done setting up we can notify systemd api
357
-	notifyReady()
358 356
 	log.G(ctx).Info("Daemon has completed initialization")
359 357
 
360 358
 	// Daemon is fully initialized. Start handling API traffic
361 359
 	// and wait for serve API to complete.
362 360
 	var (
363
-		apiWG  sync.WaitGroup
364
-		errAPI = make(chan error, 1)
361
+		apiWG      sync.WaitGroup
362
+		errAPI     = make(chan error, 1)
363
+		apiStartWG sync.WaitGroup
365 364
 	)
365
+
366
+	apiStartWG.Add(len(lss))
366 367
 	for _, ls := range lss {
367
-		apiWG.Add(1)
368
-		go func(ls net.Listener) {
369
-			defer apiWG.Done()
368
+		apiWG.Go(func() {
370 369
 			log.G(ctx).Infof("API listen on %s", ls.Addr())
371
-			if err := httpServer.Serve(ls); err != http.ErrServerClosed {
370
+			apiStartWG.Done()
371
+			if err := httpServer.Serve(ls); err != nil && !errors.Is(err, http.ErrServerClosed) {
372 372
 				log.G(ctx).WithFields(log.Fields{
373 373
 					"error":    err,
374 374
 					"listener": ls.Addr(),
... ...
@@ -379,8 +379,20 @@ func (cli *daemonCLI) start(ctx context.Context) (retErr error) {
379 379
 				default:
380 380
 				}
381 381
 			}
382
-		}(ls)
382
+		})
383 383
 	}
384
+
385
+	// Wait for all API listeners to start handling requests.
386
+	apiStartWG.Wait()
387
+
388
+	select {
389
+	case <-errAPI:
390
+		// An API listener failed to start; skip notifying systemd that we're ready.
391
+	default:
392
+		// All API listeners started handling requests; notify systemd that we're ready.
393
+		notifyReady()
394
+	}
395
+
384 396
 	apiWG.Wait()
385 397
 	close(errAPI)
386 398