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
2020-09-16 15:46:04 +02: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 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 ( )
logger := log . FromContext ( ctx )
logger . Info ( "I have to go..." )
logger . Info ( "Stopping server gracefully" )
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 ( ) {
2018-11-14 10:18:03 +01:00
defer log . WithoutContext ( ) . Info ( "Server stopped" )
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 ( )
2017-07-20 17:26:43 -05:00
}