diff --git a/CHANGELOG.md b/CHANGELOG.md index a89d08d..a3a1ff6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,11 +17,15 @@ The following emojis are used to highlight certain changes: ### Changed +- boxo 0.21 +- go-libp2p 0.35 + ### Removed ### Fixed -- Release tag version is now included in `--version` output. +- `--version` now includes the release tag +- `start` command supports a graceful shutdown and improved handling of interrupt signals ### Security diff --git a/go.mod b/go.mod index 45dac9a..85c7ac9 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.22.4 require ( github.com/CAFxX/httpcompression v0.0.9 + github.com/coreos/go-systemd/v22 v22.5.0 github.com/dustin/go-humanize v1.0.1 github.com/felixge/httpsnoop v1.0.4 github.com/ipfs/boxo v0.21.0 @@ -33,7 +34,6 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect diff --git a/server.go b/server.go index 052d957..e677a72 100644 --- a/server.go +++ b/server.go @@ -2,13 +2,19 @@ package main import ( "context" + "errors" "fmt" "log" "net" "net/http" + "os" + "os/signal" + "sync" + "syscall" "time" "github.com/CAFxX/httpcompression" + sddaemon "github.com/coreos/go-systemd/v22/daemon" "github.com/felixge/httpsnoop" "github.com/ipfs/boxo/routing/http/client" "github.com/ipfs/boxo/routing/http/server" @@ -90,9 +96,7 @@ func start(ctx context.Context, cfg *config) error { return err } - log.Printf("Starting %s %s\n", name, version) - log.Printf("Listening on %s", cfg.listenAddress) - log.Printf("Delegated Routing API on http://127.0.0.1:%s/routing/v1", port) + fmt.Printf("Starting %s %s\n", name, version) mdlw := middleware.New(middleware.Config{ Recorder: metrics.NewRecorder(metrics.Config{Prefix: "someguy"}), @@ -132,7 +136,39 @@ func start(ctx context.Context, cfg *config) error { http.Handle("/", handler) server := &http.Server{Addr: cfg.listenAddress, Handler: nil} - return server.ListenAndServe() + quit := make(chan os.Signal, 3) + var wg sync.WaitGroup + wg.Add(1) + + fmt.Printf("Listening on %s\n", cfg.listenAddress) + fmt.Printf("Delegated Routing API on http://127.0.0.1:%s/routing/v1\n", port) + + go func() { + defer wg.Done() + err := server.ListenAndServe() + if err != nil && !errors.Is(err, http.ErrServerClosed) { + logger.Fatalf("Failed to start /routing/v1 server: %v", err) + quit <- os.Interrupt + } + }() + + sddaemon.SdNotify(false, sddaemon.SdNotifyReady) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) + <-quit + sddaemon.SdNotify(false, sddaemon.SdNotifyStopping) + fmt.Printf("\nClosing /routing/v1 server...\n") + + // Attempt a graceful shutdown + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if err := server.Shutdown(ctx); err != nil { + log.Fatalf("Graceful shutdown failed:%+v\n", err) + } + + go server.Close() + wg.Wait() + fmt.Println("Shutdown finished.") + return nil } func newHost(cfg *config) (host.Host, error) {