Shutdown performs a graceful shutdown with the given context
(ctx context.Context)
| 626 | // Check if there are active connections |
| 627 | activeConns := atomic.LoadInt64(&s.activeConns) |
| 628 | if activeConns > 0 { |
| 629 | slog.Info("Waiting for active connections to finish.", "count", activeConns) |
| 630 | } |
| 631 | |
| 632 | // If process isolation is enabled, signal children to terminate |
| 633 | if s.cfg.ProcessIsolation && s.childTracker != nil { |
| 634 | childCount := s.childTracker.Count() |
| 635 | if childCount > 0 { |
| 636 | slog.Info("Signaling child processes to terminate.", "count", childCount) |
| 637 | s.childTracker.SignalAll(syscall.SIGTERM) |
| 638 | } |
| 639 | } |
| 640 | |
| 641 | // Wait for connections with context |
| 642 | done := make(chan struct{}) |
| 643 | go func() { |
| 644 | s.wg.Wait() |
| 645 | // Also wait for child processes if isolation is enabled |
| 646 | if s.cfg.ProcessIsolation && s.childTracker != nil { |
| 647 | <-s.childTracker.WaitAll() |
| 648 | } |
| 649 | close(done) |
| 650 | }() |
| 651 | |
| 652 | select { |
| 653 | case <-done: |
| 654 | slog.Info("All connections closed gracefully.") |
| 655 | case <-ctx.Done(): |
| 656 | slog.Warn("Shutdown context cancelled, force closing remaining connections.") |
| 657 | // Force kill remaining children |
| 658 | if s.cfg.ProcessIsolation && s.childTracker != nil { |
| 659 | s.childTracker.SignalAll(syscall.SIGKILL) |
| 660 | } |
| 661 | } |
| 662 | |
| 663 | // Shut down ACME managers if active |
| 664 | if s.acmeManager != nil { |
| 665 | if err := s.acmeManager.Close(); err != nil { |
| 666 | slog.Warn("ACME manager shutdown error.", "error", err) |
| 667 | } |
| 668 | } |
| 669 | if s.acmeDNSManager != nil { |
| 670 | if err := s.acmeDNSManager.Close(); err != nil { |
| 671 | slog.Warn("ACME DNS manager shutdown error.", "error", err) |
| 672 | } |
| 673 | } |
| 674 | |
| 675 | // Stop query logger (drains remaining entries) |
| 676 | if err := s.StopQueryLogging(ctx); err != nil { |
| 677 | slog.Warn("Query log shutdown deadline exceeded.", "error", err) |
| 678 | } |
| 679 | |
| 680 | // Database connections are now closed by each clientConn when it terminates |
| 681 | slog.Info("Shutdown complete.") |
| 682 | return nil |
| 683 | } |
| 684 | |
| 685 | // ActiveConnections returns the number of active connections |