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"
|
2023-02-03 15:24:05 +01:00
|
|
|
"github.com/traefik/traefik/v3/pkg/metrics"
|
|
|
|
"github.com/traefik/traefik/v3/pkg/safe"
|
|
|
|
"github.com/traefik/traefik/v3/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 {
|
2024-01-30 16:28:05 +01:00
|
|
|
watcher *ConfigurationWatcher
|
|
|
|
tcpEntryPoints TCPEntryPoints
|
|
|
|
udpEntryPoints UDPEntryPoints
|
|
|
|
observabilityMgr *middleware.ObservabilityMgr
|
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.
|
2024-01-30 16:28:05 +01:00
|
|
|
func NewServer(routinesPool *safe.Pool, entryPoints TCPEntryPoints, entryPointsUDP UDPEntryPoints, watcher *ConfigurationWatcher, observabilityMgr *middleware.ObservabilityMgr) *Server {
|
2019-11-14 16:40:05 +01:00
|
|
|
srv := &Server{
|
2024-01-30 16:28:05 +01:00
|
|
|
watcher: watcher,
|
|
|
|
tcpEntryPoints: entryPoints,
|
|
|
|
observabilityMgr: observabilityMgr,
|
|
|
|
signals: make(chan os.Signal, 1),
|
|
|
|
stopChan: make(chan bool, 1),
|
|
|
|
routinesPool: routinesPool,
|
|
|
|
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
|
|
|
|
2024-01-30 16:28:05 +01:00
|
|
|
s.observabilityMgr.Close()
|
2024-01-08 10:10:06 +02: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()
|
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
|
|
|
}
|