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
|
|
|
|
2022-11-21 17:36:05 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2023-02-03 14:24:05 +00:00
|
|
|
"github.com/traefik/traefik/v3/pkg/metrics"
|
|
|
|
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
|
|
|
|
"github.com/traefik/traefik/v3/pkg/safe"
|
|
|
|
"github.com/traefik/traefik/v3/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,
|
2022-03-21 09:42:08 +00:00
|
|
|
chainBuilder *middleware.ChainBuilder, accessLoggerMiddleware *accesslog.Handler,
|
|
|
|
) *Server {
|
2019-11-14 15:40:05 +00: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 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()
|
2022-11-21 17:36:05 +00:00
|
|
|
logger := log.Ctx(ctx)
|
|
|
|
logger.Info().Msg("I have to go...")
|
|
|
|
logger.Info().Msg("Stopping server gracefully")
|
2018-11-27 16:42:04 +00:00
|
|
|
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() {
|
2023-06-05 09:05:29 +00:00
|
|
|
//nolint:zerologlint // false-positive https://github.com/ykadowak/zerologlint/issues/3
|
2022-11-21 17:36:05 +00:00
|
|
|
defer log.Info().Msg("Server stopped")
|
2018-11-14 09:18:03 +00:00
|
|
|
|
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()
|
2022-02-09 14:32:12 +00:00
|
|
|
metrics.StopInfluxDB2()
|
2022-11-29 14:34:05 +00:00
|
|
|
metrics.StopOpenTelemetry()
|
2017-07-20 22:26:43 +00:00
|
|
|
}
|