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
}