From 70eb75cfda712751952faf1efe4f9ffc47adeb3e Mon Sep 17 00:00:00 2001 From: Dino Omanovic Date: Fri, 26 May 2017 11:45:56 +0200 Subject: [PATCH] Implemented graceful shutdown via go 1.8 Server.Shutdown(ctx) --- README.md | 1 + login/config.go | 3 +++ main.go | 27 +++++++++++++++++++-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 06ad7ba..0debb43 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ _Note for Caddy users_: Not all parameters are available in Caddy. See the table | -success-url | string | "/" | X | The url to redirect after login | | -template | string | | X | An alternative template for the login form | | -text-logging | boolean | true | - | Log in text format instead of json | +| -grace-period | go duration | 5s | - | Duration to wait after SIGINT/SIGTERM for existing requests. No new requests are accepted. | ### Environment Variables All of the above Config Options can also be applied as environment variable, where the name is written in the way: `LOGINSRV_OPTION_NAME`. diff --git a/login/config.go b/login/config.go index d3e6a01..29e7991 100644 --- a/login/config.go +++ b/login/config.go @@ -34,6 +34,7 @@ func DefaultConfig() *Config { CookieHTTPOnly: true, Backends: Options{}, Oauth: Options{}, + GracePeriod: 5 * time.Second, } } @@ -57,6 +58,7 @@ type Config struct { CookieHTTPOnly bool Backends Options Oauth Options + GracePeriod time.Duration } // Options is the configuration structure for oauth and backend provider @@ -101,6 +103,7 @@ func (c *Config) ConfigureFlagSet(f *flag.FlagSet) { f.StringVar(&c.LogoutURL, "logout-url", c.LogoutURL, "The url or path to redirect after logout") f.StringVar(&c.Template, "template", c.Template, "An alternative template for the login form") f.StringVar(&c.LoginPath, "login-path", c.LoginPath, "The path of the login resource") + f.DurationVar(&c.GracePeriod, "grace-period", c.GracePeriod, "Graceful shutdown grace period") // the -backends is deprecated, but we support it for backwards compatibility deprecatedBackends := setFunc(func(optsKvList string) error { diff --git a/main.go b/main.go index 03e7de6..2add533 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,8 @@ import ( "github.com/tarent/loginsrv/login" + "context" + "fmt" "github.com/tarent/loginsrv/logging" "net/http" "os" @@ -21,8 +23,6 @@ func main() { exit(nil, err) } - logShutdownEvent() - configToLog := *config configToLog.JwtSecret = "..." logging.LifecycleStart(applicationName, configToLog) @@ -34,15 +34,26 @@ func main() { handlerChain := logging.NewLogMiddleware(h) - exit(nil, http.ListenAndServe(config.Host+":"+config.Port, handlerChain)) -} + stop := make(chan os.Signal) + signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) + + port := config.Port + if port != "" { + port = fmt.Sprintf(":%s", port) + } + + httpSrv := &http.Server{Addr: port, Handler: handlerChain} -func logShutdownEvent() { go func() { - c := make(chan os.Signal) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - exit(<-c, nil) + if err := httpSrv.ListenAndServe(); err != nil { + logging.LifecycleStop(applicationName, nil, err) + } }() + logging.LifecycleStop(applicationName, <-stop, nil) + + ctx, _ := context.WithTimeout(context.Background(), config.GracePeriod) + + httpSrv.Shutdown(ctx) } var exit = func(signal os.Signal, err error) {