diff --git a/app/api/api.go b/app/api/api.go index bda644df..7d9719e4 100644 --- a/app/api/api.go +++ b/app/api/api.go @@ -62,7 +62,7 @@ type API interface { // been ended with Stop() or Destroy(). In this case a nil error // is returned. An ErrConfigReload error is returned if a // configuration reload has been requested. - Start() error + Start(ctx context.Context) error // Stop stops the API, some states may be kept intact such // that they can be reused after starting the API again. @@ -296,7 +296,7 @@ func (a *api) Reload() error { return nil } -func (a *api) start() error { +func (a *api) start(ctx context.Context) error { a.lock.Lock() defer a.lock.Unlock() @@ -473,7 +473,7 @@ func (a *api) start() error { }) } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(ctx, 5*time.Minute) defer cancel() cluster, err := cluster.New(ctx, cluster.Config{ @@ -521,7 +521,7 @@ func (a *api) start() error { return fmt.Errorf("failed to initialize autocert manager: %w", err) } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + ctx, cancel := context.WithTimeout(ctx, 5*time.Minute) err = manager.AcquireCertificates(ctx, cfg.Address, cfg.Host.Name) cancel() @@ -1662,7 +1662,7 @@ func (a *api) start() error { wgStart.Wait() if cfg.Debug.ForceGC > 0 { - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) a.gcTickerStop = cancel go func(ctx context.Context) { @@ -1715,13 +1715,13 @@ func (a *api) start() error { return nil } -func (a *api) Start() error { - if err := a.start(); err != nil { +func (a *api) Start(ctx context.Context) error { + if err := a.start(ctx); err != nil { a.stop() return err } - // Block until is an error from the servers + // Block until there's an error from the servers err := <-a.errorChan return err diff --git a/main.go b/main.go index 377af7e5..f021769d 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "os" "os/signal" @@ -22,7 +23,9 @@ func main() { os.Exit(1) } - go func() { + ctx, cancel := context.WithCancel(context.Background()) + + go func(ctx context.Context) { defer func() { if proc, err := os.FindProcess(os.Getpid()); err == nil { proc.Signal(os.Interrupt) @@ -30,7 +33,7 @@ func main() { }() for { - if err := app.Start(); err != api.ErrConfigReload { + if err := app.Start(ctx); err != api.ErrConfigReload { if err != nil { logger.Error().WithError(err).Log("Failed to start API") } @@ -47,13 +50,15 @@ func main() { break } } - }() + }(ctx) // Wait for interrupt signal to gracefully shutdown the app quit := make(chan os.Signal, 1) signal.Notify(quit, os.Interrupt) <-quit + cancel() + // Stop the app app.Destroy() }