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 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")

View file

@ -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()

View file

@ -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()
} }
} }
} }

View file

@ -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()
}
}
}