From e1cc8cc6d388f2310c6dc3c2bffee040191e24d6 Mon Sep 17 00:00:00 2001 From: Ryan Gonzalez Date: Tue, 5 Sep 2023 15:20:47 -0500 Subject: [PATCH] Shut down cleanly when 'api serve' is interrupted This will properly close the db and, more particularly, flush out any profile files being written. Otherwise, they can end up empty or truncated. Signed-off-by: Ryan Gonzalez --- cmd/api_serve.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/cmd/api_serve.go b/cmd/api_serve.go index 7c19d2ef2..9b6d3402a 100644 --- a/cmd/api_serve.go +++ b/cmd/api_serve.go @@ -1,11 +1,15 @@ package cmd import ( + stdcontext "context" + "errors" "fmt" "net" "net/http" "net/url" "os" + "os/signal" + "syscall" "github.com/aptly-dev/aptly/api" "github.com/aptly-dev/aptly/systemd/activation" @@ -55,6 +59,17 @@ func aptlyAPIServe(cmd *commander.Command, args []string) error { listen := context.Flags().Lookup("listen").Value.String() fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen) + server := http.Server{Handler: api.Router(context)} + + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM) + go (func() { + if _, ok := <-sigchan; ok { + server.Shutdown(stdcontext.Background()) + } + })() + defer close(sigchan) + listenURL, err := url.Parse(listen) if err == nil && listenURL.Scheme == "unix" { file := listenURL.Path @@ -67,19 +82,17 @@ func aptlyAPIServe(cmd *commander.Command, args []string) error { } defer listener.Close() - err = http.Serve(listener, api.Router(context)) - if err != nil { - return fmt.Errorf("unable to serve: %s", err) - } - return nil + err = server.Serve(listener) + } else { + server.Addr = listen + err = server.ListenAndServe() } - err = http.ListenAndServe(listen, api.Router(context)) - if err != nil { + if err != nil && !errors.Is(err, http.ErrServerClosed) { return fmt.Errorf("unable to serve: %s", err) } - return err + return nil } func makeCmdAPIServe() *commander.Command {