2017-04-17 20:47:53 +00:00
|
|
|
package server
|
2016-01-13 21:45:49 +00:00
|
|
|
|
|
|
|
import (
|
2016-08-16 15:26:10 +00:00
|
|
|
"context"
|
2020-11-06 08:26:03 +00:00
|
|
|
"errors"
|
2016-02-26 14:29:53 +00:00
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"time"
|
2016-02-19 22:55:23 +00:00
|
|
|
|
2020-09-16 13:46:04 +00:00
|
|
|
"github.com/traefik/traefik/v2/pkg/log"
|
|
|
|
"github.com/traefik/traefik/v2/pkg/metrics"
|
|
|
|
"github.com/traefik/traefik/v2/pkg/middlewares/accesslog"
|
|
|
|
"github.com/traefik/traefik/v2/pkg/safe"
|
|
|
|
"github.com/traefik/traefik/v2/pkg/server/middleware"
|
2016-01-13 21:45:49 +00:00
|
|
|
)
|
|
|
|
|
2020-05-11 10:06:07 +00:00
|
|
|
// Server is the reverse-proxy/load-balancer engine.
|
2016-01-13 21:45:49 +00:00
|
|
|
type Server struct {
|
2019-11-14 15:40:05 +00:00
|
|
|
watcher *ConfigurationWatcher
|
|
|
|
tcpEntryPoints TCPEntryPoints
|
2020-02-11 00:26:04 +00:00
|
|
|
udpEntryPoints UDPEntryPoints
|
2019-11-14 15:40:05 +00:00
|
|
|
chainBuilder *middleware.ChainBuilder
|
2018-04-23 13:30:03 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
accessLoggerMiddleware *accesslog.Handler
|
2019-06-27 22:16:04 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
signals chan os.Signal
|
|
|
|
stopChan chan bool
|
2019-06-27 22:16:04 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
routinesPool *safe.Pool
|
2018-11-14 09:18:03 +00:00
|
|
|
}
|
|
|
|
|
2016-01-13 21:45:49 +00:00
|
|
|
// NewServer returns an initialized Server.
|
2020-02-11 00:26:04 +00:00
|
|
|
func NewServer(routinesPool *safe.Pool, entryPoints TCPEntryPoints, entryPointsUDP UDPEntryPoints, watcher *ConfigurationWatcher,
|
2019-11-14 15:40:05 +00:00
|
|
|
chainBuilder *middleware.ChainBuilder, accessLoggerMiddleware *accesslog.Handler) *Server {
|
|
|
|
srv := &Server{
|
|
|
|
watcher: watcher,
|
|
|
|
tcpEntryPoints: entryPoints,
|
|
|
|
chainBuilder: chainBuilder,
|
|
|
|
accessLoggerMiddleware: accessLoggerMiddleware,
|
|
|
|
signals: make(chan os.Signal, 1),
|
|
|
|
stopChan: make(chan bool, 1),
|
|
|
|
routinesPool: routinesPool,
|
2020-02-11 00:26:04 +00:00
|
|
|
udpEntryPoints: entryPointsUDP,
|
2019-09-06 13:08:04 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
srv.configureSignals()
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
return srv
|
2016-01-13 21:45:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 10:06:07 +00:00
|
|
|
// Start starts the server and Stop/Close it when context is Done.
|
2018-11-27 16:42:04 +00:00
|
|
|
func (s *Server) Start(ctx context.Context) {
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
logger := log.FromContext(ctx)
|
|
|
|
logger.Info("I have to go...")
|
|
|
|
logger.Info("Stopping server gracefully")
|
|
|
|
s.Stop()
|
|
|
|
}()
|
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
s.tcpEntryPoints.Start()
|
2020-02-11 00:26:04 +00:00
|
|
|
s.udpEntryPoints.Start()
|
2019-11-14 15:40:05 +00:00
|
|
|
s.watcher.Start()
|
|
|
|
|
2020-02-03 16:56:04 +00:00
|
|
|
s.routinesPool.GoCtx(s.listenSignals)
|
2016-10-25 15:59:39 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
// Wait blocks until the server shutdown.
|
2017-11-24 18:18:03 +00:00
|
|
|
func (s *Server) Wait() {
|
|
|
|
<-s.stopChan
|
2016-01-13 21:45:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 10:06:07 +00:00
|
|
|
// Stop stops the server.
|
2017-11-24 18:18:03 +00:00
|
|
|
func (s *Server) Stop() {
|
2018-11-14 09:18:03 +00:00
|
|
|
defer log.WithoutContext().Info("Server stopped")
|
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
s.tcpEntryPoints.Stop()
|
2020-02-11 00:26:04 +00:00
|
|
|
s.udpEntryPoints.Stop()
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2017-11-24 18:18:03 +00:00
|
|
|
s.stopChan <- true
|
2016-01-13 21:45:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 10:06:07 +00:00
|
|
|
// Close destroys the server.
|
2017-11-24 18:18:03 +00:00
|
|
|
func (s *Server) Close() {
|
2018-03-14 12:14:03 +00:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
2019-11-14 15:40:05 +00:00
|
|
|
|
2016-07-13 15:50:57 +00:00
|
|
|
go func(ctx context.Context) {
|
|
|
|
<-ctx.Done()
|
2020-11-06 08:26:03 +00:00
|
|
|
if errors.Is(ctx.Err(), context.Canceled) {
|
2016-07-13 15:50:57 +00:00
|
|
|
return
|
2020-11-06 08:26:03 +00:00
|
|
|
} else if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
2018-03-14 12:14:03 +00:00
|
|
|
panic("Timeout while stopping traefik, killing instance ✝")
|
2016-07-13 15:50:57 +00:00
|
|
|
}
|
|
|
|
}(ctx)
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
stopMetricsClients()
|
2019-11-14 15:40:05 +00:00
|
|
|
|
2020-02-03 16:56:04 +00:00
|
|
|
s.routinesPool.Stop()
|
2019-11-14 15:40:05 +00:00
|
|
|
|
2017-11-24 18:18:03 +00:00
|
|
|
signal.Stop(s.signals)
|
|
|
|
close(s.signals)
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
close(s.stopChan)
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2019-11-14 15:40:05 +00:00
|
|
|
s.chainBuilder.Close()
|
2018-11-14 09:18:03 +00:00
|
|
|
|
2016-07-13 15:50:57 +00:00
|
|
|
cancel()
|
2016-01-13 21:45:49 +00:00
|
|
|
}
|
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
func stopMetricsClients() {
|
|
|
|
metrics.StopDatadog()
|
|
|
|
metrics.StopStatsd()
|
2017-11-08 14:14:03 +00:00
|
|
|
metrics.StopInfluxDB()
|
2017-07-20 22:26:43 +00:00
|
|
|
}
|