The daemon previously signaled systemd (READY=1) before the API Serve loops
were started.
Move the readiness notification until after the API listeners are serving
to reduce the window where systemd considers the daemon ready but the
HTTP accept loop has not yet started.
While modifying, also use `WaitGroup.Go` for a slight cleanup.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -345,22 +345,22 @@ func (cli *daemonCLI) start(ctx context.Context) (err error) {
|
| 345 | 345 |
|
| 346 | 346 |
cli.setupConfigReloadTrap() |
| 347 | 347 |
|
| 348 |
- // after the daemon is done setting up we can notify systemd api |
|
| 349 |
- notifyReady() |
|
| 350 | 348 |
log.G(ctx).Info("Daemon has completed initialization")
|
| 351 | 349 |
|
| 352 | 350 |
// Daemon is fully initialized. Start handling API traffic |
| 353 | 351 |
// and wait for serve API to complete. |
| 354 | 352 |
var ( |
| 355 |
- apiWG sync.WaitGroup |
|
| 356 |
- errAPI = make(chan error, 1) |
|
| 353 |
+ apiWG sync.WaitGroup |
|
| 354 |
+ errAPI = make(chan error, 1) |
|
| 355 |
+ apiStartWG sync.WaitGroup |
|
| 357 | 356 |
) |
| 357 |
+ |
|
| 358 |
+ apiStartWG.Add(len(lss)) |
|
| 358 | 359 |
for _, ls := range lss {
|
| 359 |
- apiWG.Add(1) |
|
| 360 |
- go func(ls net.Listener) {
|
|
| 361 |
- defer apiWG.Done() |
|
| 360 |
+ apiWG.Go(func() {
|
|
| 362 | 361 |
log.G(ctx).Infof("API listen on %s", ls.Addr())
|
| 363 |
- if err := httpServer.Serve(ls); err != http.ErrServerClosed {
|
|
| 362 |
+ apiStartWG.Done() |
|
| 363 |
+ if err := httpServer.Serve(ls); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
| 364 | 364 |
log.G(ctx).WithFields(log.Fields{
|
| 365 | 365 |
"error": err, |
| 366 | 366 |
"listener": ls.Addr(), |
| ... | ... |
@@ -371,8 +371,20 @@ func (cli *daemonCLI) start(ctx context.Context) (err error) {
|
| 371 | 371 |
default: |
| 372 | 372 |
} |
| 373 | 373 |
} |
| 374 |
- }(ls) |
|
| 374 |
+ }) |
|
| 375 | 375 |
} |
| 376 |
+ |
|
| 377 |
+ // Wait for all API listeners to start handling requests. |
|
| 378 |
+ apiStartWG.Wait() |
|
| 379 |
+ |
|
| 380 |
+ select {
|
|
| 381 |
+ case <-errAPI: |
|
| 382 |
+ // An API listener failed to start; skip notifying systemd that we're ready. |
|
| 383 |
+ default: |
|
| 384 |
+ // All API listeners started handling requests; notify systemd that we're ready. |
|
| 385 |
+ notifyReady() |
|
| 386 |
+ } |
|
| 387 |
+ |
|
| 376 | 388 |
apiWG.Wait() |
| 377 | 389 |
close(errAPI) |
| 378 | 390 |
|