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