Use context in Server
This commit is contained in:
parent
526a04d4c8
commit
f99363674b
5 changed files with 47 additions and 36 deletions
22
cmd/context.go
Normal file
22
cmd/context.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContextWithSignal create a context cancelled when SIGINT or SIGTERM are notified
|
||||||
|
func ContextWithSignal(ctx context.Context) context.Context {
|
||||||
|
newCtx, cancel := context.WithCancel(ctx)
|
||||||
|
signals := make(chan os.Signal)
|
||||||
|
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-signals:
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return newCtx
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
fmtlog "log"
|
fmtlog "log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -173,7 +174,8 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
||||||
acme.Get().SetConfigListenerChan(make(chan types.Configuration))
|
acme.Get().SetConfigListenerChan(make(chan types.Configuration))
|
||||||
svr.AddListener(acme.Get().ListenConfiguration)
|
svr.AddListener(acme.Get().ListenConfiguration)
|
||||||
}
|
}
|
||||||
svr.Start()
|
ctx := cmd.ContextWithSignal(context.Background())
|
||||||
|
svr.StartWithContext(ctx)
|
||||||
defer svr.Close()
|
defer svr.Close()
|
||||||
|
|
||||||
sent, err := daemon.SdNotify(false, "READY=1")
|
sent, err := daemon.SdNotify(false, "READY=1")
|
||||||
|
|
|
@ -205,6 +205,23 @@ func (s *Server) Start() {
|
||||||
go s.listenSignals()
|
go s.listenSignals()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartWithContext starts the server and Stop/Close it when context is Done
|
||||||
|
func (s *Server) StartWithContext(ctx context.Context) {
|
||||||
|
go func() {
|
||||||
|
defer s.Close()
|
||||||
|
<-ctx.Done()
|
||||||
|
log.Info("I have to go...")
|
||||||
|
reqAcceptGraceTimeOut := time.Duration(s.globalConfiguration.LifeCycle.RequestAcceptGraceTimeout)
|
||||||
|
if reqAcceptGraceTimeOut > 0 {
|
||||||
|
log.Infof("Waiting %s for incoming requests to cease", reqAcceptGraceTimeOut)
|
||||||
|
time.Sleep(reqAcceptGraceTimeOut)
|
||||||
|
}
|
||||||
|
log.Info("Stopping server gracefully")
|
||||||
|
s.Stop()
|
||||||
|
}()
|
||||||
|
s.Start()
|
||||||
|
}
|
||||||
|
|
||||||
// Wait blocks until server is shutted down.
|
// Wait blocks until server is shutted down.
|
||||||
func (s *Server) Wait() {
|
func (s *Server) Wait() {
|
||||||
<-s.stopChan
|
<-s.stopChan
|
||||||
|
@ -235,14 +252,13 @@ func (s *Server) Stop() {
|
||||||
|
|
||||||
// Close destroys the server
|
// Close destroys the server
|
||||||
func (s *Server) Close() {
|
func (s *Server) Close() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(s.globalConfiguration.LifeCycle.GraceTimeOut))
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
go func(ctx context.Context) {
|
go func(ctx context.Context) {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
if ctx.Err() == context.Canceled {
|
if ctx.Err() == context.Canceled {
|
||||||
return
|
return
|
||||||
} else if ctx.Err() == context.DeadlineExceeded {
|
} else if ctx.Err() == context.DeadlineExceeded {
|
||||||
log.Warn("Timeout while stopping traefik, killing instance ✝")
|
panic("Timeout while stopping traefik, killing instance ✝")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}(ctx)
|
}(ctx)
|
||||||
stopMetricsClients()
|
stopMetricsClients()
|
||||||
|
|
|
@ -5,13 +5,12 @@ package server
|
||||||
import (
|
import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) configureSignals() {
|
func (s *Server) configureSignals() {
|
||||||
signal.Notify(s.signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
|
signal.Notify(s.signals, syscall.SIGUSR1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) listenSignals() {
|
func (s *Server) listenSignals() {
|
||||||
|
@ -30,15 +29,6 @@ func (s *Server) listenSignals() {
|
||||||
if err := log.RotateFile(); err != nil {
|
if err := log.RotateFile(); err != nil {
|
||||||
log.Errorf("Error rotating traefik log: %s", err)
|
log.Errorf("Error rotating traefik log: %s", err)
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
log.Infof("I have to go... %+v", sig)
|
|
||||||
reqAcceptGraceTimeOut := time.Duration(s.globalConfiguration.LifeCycle.RequestAcceptGraceTimeout)
|
|
||||||
if reqAcceptGraceTimeOut > 0 {
|
|
||||||
log.Infof("Waiting %s for incoming requests to cease", reqAcceptGraceTimeOut)
|
|
||||||
time.Sleep(reqAcceptGraceTimeOut)
|
|
||||||
}
|
|
||||||
log.Info("Stopping server gracefully")
|
|
||||||
s.Stop()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,6 @@
|
||||||
|
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
func (s *Server) configureSignals() {}
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
func (s *Server) listenSignals() {}
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) configureSignals() {
|
|
||||||
signal.Notify(s.signals, syscall.SIGINT, syscall.SIGTERM)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) listenSignals() {
|
|
||||||
for {
|
|
||||||
sig := <-s.signals
|
|
||||||
switch sig {
|
|
||||||
default:
|
|
||||||
log.Infof("I have to go... %+v", sig)
|
|
||||||
log.Info("Stopping server")
|
|
||||||
s.Stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue