Use context in Server

This commit is contained in:
SALLEYRON Julien 2018-03-14 13:14:03 +01:00 committed by Traefiker Bot
parent 526a04d4c8
commit f99363674b
5 changed files with 47 additions and 36 deletions

22
cmd/context.go Normal file
View 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
}

View file

@ -1,6 +1,7 @@
package main
import (
"context"
"encoding/json"
fmtlog "log"
"net/http"
@ -173,7 +174,8 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
acme.Get().SetConfigListenerChan(make(chan types.Configuration))
svr.AddListener(acme.Get().ListenConfiguration)
}
svr.Start()
ctx := cmd.ContextWithSignal(context.Background())
svr.StartWithContext(ctx)
defer svr.Close()
sent, err := daemon.SdNotify(false, "READY=1")

View file

@ -205,6 +205,23 @@ func (s *Server) Start() {
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.
func (s *Server) Wait() {
<-s.stopChan
@ -235,14 +252,13 @@ func (s *Server) Stop() {
// Close destroys the server
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) {
<-ctx.Done()
if ctx.Err() == context.Canceled {
return
} else if ctx.Err() == context.DeadlineExceeded {
log.Warn("Timeout while stopping traefik, killing instance ✝")
os.Exit(1)
panic("Timeout while stopping traefik, killing instance ✝")
}
}(ctx)
stopMetricsClients()

View file

@ -5,13 +5,12 @@ package server
import (
"os/signal"
"syscall"
"time"
"github.com/containous/traefik/log"
)
func (s *Server) configureSignals() {
signal.Notify(s.signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
signal.Notify(s.signals, syscall.SIGUSR1)
}
func (s *Server) listenSignals() {
@ -30,15 +29,6 @@ func (s *Server) listenSignals() {
if err := log.RotateFile(); err != nil {
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()
}
}
}

View file

@ -2,25 +2,6 @@
package server
import (
"os/signal"
"syscall"
func (s *Server) configureSignals() {}
"github.com/containous/traefik/log"
)
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()
}
}
}
func (s *Server) listenSignals() {}