add signal handler for clean shutdown

This commit is contained in:
Ben McClelland
2023-06-25 10:01:54 -07:00
parent c4f5f958eb
commit 1d476c6d4d
5 changed files with 70 additions and 5 deletions

View File

@@ -34,6 +34,9 @@ build: $(BIN)
$(BIN):
$(GOBUILD) $(LDFLAGS) -o $(BIN) cmd/$(BIN)/*.go
testbin:
$(GOBUILD) $(LDFLAGS) -o $(BIN) -cover -race cmd/$(BIN)/*.go
.PHONY: test
test:
$(GOTEST) ./...

View File

@@ -15,6 +15,7 @@
package main
import (
"context"
"crypto/tls"
"fmt"
"log"
@@ -47,6 +48,8 @@ var (
)
func main() {
setupSignalHandler()
app := initApp()
app.Commands = []*cli.Command{
@@ -56,7 +59,14 @@ func main() {
testCommand(),
}
if err := app.Run(os.Args); err != nil {
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-sigDone
fmt.Fprintf(os.Stderr, "terminating signal caught, shutting down\n")
cancel()
}()
if err := app.RunContext(ctx, os.Args); err != nil {
log.Fatal(err)
}
}
@@ -134,7 +144,7 @@ func initFlags() []cli.Flag {
}
}
func runGateway(be backend.Backend, s auth.Storer) error {
func runGateway(ctx *cli.Context, be backend.Backend, s auth.Storer) error {
app := fiber.New(fiber.Config{
AppName: "versitygw",
ServerHeader: "VERSITYGW",
@@ -180,5 +190,15 @@ func runGateway(be backend.Backend, s auth.Storer) error {
return fmt.Errorf("init gateway: %v", err)
}
return srv.Serve()
c := make(chan error, 1)
go func() { c <- srv.Serve() }()
select {
case <-ctx.Done():
be.Shutdown()
return ctx.Err()
case err := <-c:
be.Shutdown()
return err
}
}

View File

@@ -49,5 +49,5 @@ func runPosix(ctx *cli.Context) error {
return fmt.Errorf("init posix: %v", err)
}
return runGateway(be, be)
return runGateway(ctx, be, be)
}

View File

@@ -69,5 +69,5 @@ func runScoutfs(ctx *cli.Context) error {
return fmt.Errorf("init scoutfs: %v", err)
}
return runGateway(be, be)
return runGateway(ctx, be, be)
}

42
cmd/versitygw/singal.go Normal file
View File

@@ -0,0 +1,42 @@
// Copyright 2023 Versity Software
// This file is licensed under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
var (
sigDone = make(chan bool, 1)
)
func setupSignalHandler() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
go func() {
for sig := range sigs {
fmt.Fprintf(os.Stderr, "caught signal %v\n", sig)
switch sig {
case syscall.SIGINT, syscall.SIGTERM:
sigDone <- true
case syscall.SIGHUP:
}
}
}()
}