From ce914abb57e4cc4f18ef768a275108047a6c1b3d Mon Sep 17 00:00:00 2001 From: Ophestra Date: Wed, 11 Mar 2026 02:00:55 +0900 Subject: [PATCH] cmd/pkgserver: gracefully shut down on signal Signed-off-by: Ophestra --- cmd/pkgserver/main.go | 32 +++++++++++++++++++++++++------- cmd/pkgserver/ui.go | 1 + 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/cmd/pkgserver/main.go b/cmd/pkgserver/main.go index 19fd440..9814ea1 100644 --- a/cmd/pkgserver/main.go +++ b/cmd/pkgserver/main.go @@ -8,6 +8,7 @@ import ( "os" "os/signal" "syscall" + "time" "hakurei.app/command" "hakurei.app/container/check" @@ -16,7 +17,8 @@ import ( "hakurei.app/message" ) -//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && tsc -p ui/static" +const shutdownTimeout = 15 * time.Second + func main() { log.SetFlags(0) log.SetPrefix("pkgserver: ") @@ -65,9 +67,23 @@ func main() { if err := index.populate(cache, report); err != nil { return err } - uiRoutes(http.DefaultServeMux) - apiRoutes(http.DefaultServeMux, &index) - return http.ListenAndServe(flagAddr, nil) + + var mux http.ServeMux + uiRoutes(&mux) + apiRoutes(&mux, &index) + server := http.Server{ + Addr: flagAddr, + Handler: &mux, + } + go func() { + <-ctx.Done() + c, cancel := context.WithTimeout(context.Background(), shutdownTimeout) + defer cancel() + if err := server.Shutdown(c); err != nil { + log.Fatal(err) + } + }() + return server.ListenAndServe() }).Flag( &flagBaseDir, "b", command.StringFlag(""), @@ -77,8 +93,10 @@ func main() { "addr", command.StringFlag(":8067"), "TCP network address to listen on", ) - c.MustParse(os.Args[1:], func(e error) { - log.Fatal(e) + c.MustParse(os.Args[1:], func(err error) { + if errors.Is(err, http.ErrServerClosed) { + os.Exit(0) + } + log.Fatal(err) }) - } diff --git a/cmd/pkgserver/ui.go b/cmd/pkgserver/ui.go index 8a7ae10..e6e5eb7 100644 --- a/cmd/pkgserver/ui.go +++ b/cmd/pkgserver/ui.go @@ -5,6 +5,7 @@ import ( "net/http" ) +//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && tsc -p ui/static" //go:embed ui/* var content embed.FS