Switch duration configuration parameters over to flaeg.Duration.

This commit is contained in:
Timo Reimann 2017-03-27 11:51:53 +02:00
parent e375ba98f0
commit 056fe9ac0a
5 changed files with 75 additions and 48 deletions

View file

@ -9,6 +9,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/containous/flaeg"
"github.com/containous/traefik/acme" "github.com/containous/traefik/acme"
"github.com/containous/traefik/provider" "github.com/containous/traefik/provider"
"github.com/containous/traefik/types" "github.com/containous/traefik/types"
@ -23,7 +24,7 @@ type TraefikConfiguration struct {
// GlobalConfiguration holds global configuration (with providers, etc.). // GlobalConfiguration holds global configuration (with providers, etc.).
// It's populated from the traefik configuration file passed as an argument to the binary. // It's populated from the traefik configuration file passed as an argument to the binary.
type GlobalConfiguration struct { type GlobalConfiguration struct {
GraceTimeOut int64 `short:"g" description:"Duration to give active requests a chance to finish during hot-reload"` GraceTimeOut flaeg.Duration `short:"g" description:"Duration to give active requests a chance to finish during hot-reload"`
Debug bool `short:"d" description:"Enable debug mode"` Debug bool `short:"d" description:"Enable debug mode"`
CheckNewVersion bool `description:"Periodically check if a new version has been released"` CheckNewVersion bool `description:"Periodically check if a new version has been released"`
AccessLogsFile string `description:"Access logs file"` AccessLogsFile string `description:"Access logs file"`
@ -34,7 +35,7 @@ type GlobalConfiguration struct {
Constraints types.Constraints `description:"Filter services by constraint, matching with service tags"` Constraints types.Constraints `description:"Filter services by constraint, matching with service tags"`
ACME *acme.ACME `description:"Enable ACME (Let's Encrypt): automatic SSL"` ACME *acme.ACME `description:"Enable ACME (Let's Encrypt): automatic SSL"`
DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint"` DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint"`
ProvidersThrottleDuration time.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time."` ProvidersThrottleDuration flaeg.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time."`
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used"` MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used"`
InsecureSkipVerify bool `description:"Disable SSL certificate verification"` InsecureSkipVerify bool `description:"Disable SSL certificate verification"`
Retry *Retry `description:"Enable retry sending request if network error"` Retry *Retry `description:"Enable retry sending request if network error"`
@ -457,14 +458,14 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
func NewTraefikConfiguration() *TraefikConfiguration { func NewTraefikConfiguration() *TraefikConfiguration {
return &TraefikConfiguration{ return &TraefikConfiguration{
GlobalConfiguration: GlobalConfiguration{ GlobalConfiguration: GlobalConfiguration{
GraceTimeOut: 10, GraceTimeOut: flaeg.Duration(10 * time.Second),
AccessLogsFile: "", AccessLogsFile: "",
TraefikLogsFile: "", TraefikLogsFile: "",
LogLevel: "ERROR", LogLevel: "ERROR",
EntryPoints: map[string]*EntryPoint{}, EntryPoints: map[string]*EntryPoint{},
Constraints: types.Constraints{}, Constraints: types.Constraints{},
DefaultEntryPoints: []string{}, DefaultEntryPoints: []string{},
ProvidersThrottleDuration: time.Duration(2 * time.Second), ProvidersThrottleDuration: flaeg.Duration(2 * time.Second),
MaxIdleConnsPerHost: 200, MaxIdleConnsPerHost: 200,
CheckNewVersion: true, CheckNewVersion: true,
}, },

View file

@ -9,13 +9,15 @@
# Global configuration # Global configuration
################################################################ ################################################################
# Timeout in seconds. # Duration to give active requests a chance to finish during hot-reloads.
# Duration to give active requests a chance to finish during hot-reloads # Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw
# values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 10 # Default: "10s"
# #
# graceTimeOut = 10 # graceTimeOut = "10s"
# Enable debug mode # Enable debug mode
# #
@ -56,11 +58,14 @@
# Backends throttle duration: minimum duration in seconds between 2 events from providers # Backends throttle duration: minimum duration in seconds between 2 events from providers
# before applying a new configuration. It avoids unnecessary reloads if multiples events # before applying a new configuration. It avoids unnecessary reloads if multiples events
# are sent in a short amount of time. # are sent in a short amount of time.
# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw
# values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: "2" # Default: "2s"
# #
# ProvidersThrottleDuration = "5" # ProvidersThrottleDuration = "2s"
# If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. # If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
# If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value. # If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value.
@ -932,19 +937,25 @@ domain = "marathon.localhost"
# dcosToken = "xxxxxx" # dcosToken = "xxxxxx"
# Override DialerTimeout # Override DialerTimeout
# Amount of time in seconds to allow the Marathon provider to wait to open a TCP # Amount of time to allow the Marathon provider to wait to open a TCP connection
# connection to a Marathon master # to a Marathon master.
# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw
# values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 60 # Default: "60s"
# dialerTimeout = 5 # dialerTimeout = "60s"
# Set the TCP Keep Alive interval (in seconds) for the Marathon HTTP Client # Set the TCP Keep Alive interval for the Marathon HTTP Client.
# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw
# values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 10 # Default: "10s"
# #
# keepAlive = 10 # keepAlive = "10s"
``` ```
Labels can be used on containers to override default behaviour: Labels can be used on containers to override default behaviour:

View file

@ -13,6 +13,7 @@ import (
"github.com/BurntSushi/ty/fun" "github.com/BurntSushi/ty/fun"
"github.com/cenk/backoff" "github.com/cenk/backoff"
"github.com/containous/flaeg"
"github.com/containous/traefik/job" "github.com/containous/traefik/job"
"github.com/containous/traefik/log" "github.com/containous/traefik/log"
"github.com/containous/traefik/safe" "github.com/containous/traefik/safe"
@ -25,15 +26,15 @@ var _ Provider = (*Marathon)(nil)
// Marathon holds configuration of the Marathon provider. // Marathon holds configuration of the Marathon provider.
type Marathon struct { type Marathon struct {
BaseProvider BaseProvider
Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon"` Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon"`
Domain string `description:"Default domain used"` Domain string `description:"Default domain used"`
ExposedByDefault bool `description:"Expose Marathon apps by default"` ExposedByDefault bool `description:"Expose Marathon apps by default"`
GroupsAsSubDomains bool `description:"Convert Marathon groups to subdomains"` GroupsAsSubDomains bool `description:"Convert Marathon groups to subdomains"`
DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header"` DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header"`
MarathonLBCompatibility bool `description:"Add compatibility with marathon-lb labels"` MarathonLBCompatibility bool `description:"Add compatibility with marathon-lb labels"`
TLS *ClientTLS `description:"Enable Docker TLS support"` TLS *ClientTLS `description:"Enable Docker TLS support"`
DialerTimeout time.Duration `description:"Set a non-default connection timeout for Marathon"` DialerTimeout flaeg.Duration `description:"Set a non-default connection timeout for Marathon"`
KeepAlive time.Duration `description:"Set a non-default TCP Keep Alive time in seconds"` KeepAlive flaeg.Duration `description:"Set a non-default TCP Keep Alive time in seconds"`
Basic *MarathonBasic Basic *MarathonBasic
marathonClient marathon.Marathon marathonClient marathon.Marathon
} }
@ -71,8 +72,8 @@ func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage,
config.HTTPClient = &http.Client{ config.HTTPClient = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
DialContext: (&net.Dialer{ DialContext: (&net.Dialer{
KeepAlive: provider.KeepAlive * time.Second, KeepAlive: time.Duration(provider.KeepAlive),
Timeout: time.Second * provider.DialerTimeout, Timeout: time.Duration(provider.DialerTimeout),
}).DialContext, }).DialContext,
TLSClientConfig: TLSConfig, TLSClientConfig: TLSConfig,
}, },

View file

@ -20,6 +20,8 @@ import (
"syscall" "syscall"
"time" "time"
"sync"
"github.com/codegangsta/negroni" "github.com/codegangsta/negroni"
"github.com/containous/mux" "github.com/containous/mux"
"github.com/containous/traefik/cluster" "github.com/containous/traefik/cluster"
@ -35,7 +37,6 @@ import (
"github.com/vulcand/oxy/forward" "github.com/vulcand/oxy/forward"
"github.com/vulcand/oxy/roundrobin" "github.com/vulcand/oxy/roundrobin"
"github.com/vulcand/oxy/utils" "github.com/vulcand/oxy/utils"
"sync"
) )
var oxyLogger = &OxyLogger{} var oxyLogger = &OxyLogger{}
@ -120,8 +121,9 @@ func (server *Server) Stop() {
wg.Add(1) wg.Add(1)
go func(serverEntryPointName string, serverEntryPoint *serverEntryPoint) { go func(serverEntryPointName string, serverEntryPoint *serverEntryPoint) {
defer wg.Done() defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(server.globalConfiguration.GraceTimeOut)*time.Second) graceTimeOut := time.Duration(server.globalConfiguration.GraceTimeOut)
log.Debugf("Waiting %d seconds before killing connections on entrypoint %s...", server.globalConfiguration.GraceTimeOut, serverEntryPointName) ctx, cancel := context.WithTimeout(context.Background(), graceTimeOut)
log.Debugf("Waiting %s seconds before killing connections on entrypoint %s...", graceTimeOut, serverEntryPointName)
if err := serverEntryPoint.httpServer.Shutdown(ctx); err != nil { if err := serverEntryPoint.httpServer.Shutdown(ctx); err != nil {
log.Debugf("Wait is over due to: %s", err) log.Debugf("Wait is over due to: %s", err)
serverEntryPoint.httpServer.Close() serverEntryPoint.httpServer.Close()
@ -136,7 +138,7 @@ func (server *Server) Stop() {
// Close destroys the server // Close destroys the server
func (server *Server) Close() { func (server *Server) Close() {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(server.globalConfiguration.GraceTimeOut)*time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(server.globalConfiguration.GraceTimeOut))
go func(ctx context.Context) { go func(ctx context.Context) {
<-ctx.Done() <-ctx.Done()
if ctx.Err() == context.Canceled { if ctx.Err() == context.Canceled {
@ -231,16 +233,17 @@ func (server *Server) listenProviders(stop chan bool) {
} else { } else {
lastConfigs.Set(configMsg.ProviderName, &configMsg) lastConfigs.Set(configMsg.ProviderName, &configMsg)
lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time) lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time)
if time.Now().After(lastReceivedConfigurationValue.Add(time.Duration(server.globalConfiguration.ProvidersThrottleDuration))) { providersThrottleDuration := time.Duration(server.globalConfiguration.ProvidersThrottleDuration)
if time.Now().After(lastReceivedConfigurationValue.Add(providersThrottleDuration)) {
log.Debugf("Last %s config received more than %s, OK", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String()) log.Debugf("Last %s config received more than %s, OK", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String())
// last config received more than n s ago // last config received more than n s ago
server.configurationValidatedChan <- configMsg server.configurationValidatedChan <- configMsg
} else { } else {
log.Debugf("Last %s config received less than %s, waiting...", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String()) log.Debugf("Last %s config received less than %s, waiting...", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String())
safe.Go(func() { safe.Go(func() {
<-time.After(server.globalConfiguration.ProvidersThrottleDuration) <-time.After(providersThrottleDuration)
lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time) lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time)
if time.Now().After(lastReceivedConfigurationValue.Add(time.Duration(server.globalConfiguration.ProvidersThrottleDuration))) { if time.Now().After(lastReceivedConfigurationValue.Add(time.Duration(providersThrottleDuration))) {
log.Debugf("Waited for %s config, OK", configMsg.ProviderName) log.Debugf("Waited for %s config, OK", configMsg.ProviderName)
if lastConfig, ok := lastConfigs.Get(configMsg.ProviderName); ok { if lastConfig, ok := lastConfigs.Get(configMsg.ProviderName); ok {
server.configurationValidatedChan <- *lastConfig.(*types.ConfigMessage) server.configurationValidatedChan <- *lastConfig.(*types.ConfigMessage)

View file

@ -2,13 +2,15 @@
# Global configuration # Global configuration
################################################################ ################################################################
# Timeout in seconds. # Duration to give active requests a chance to finish during hot-reloads.
# Duration to give active requests a chance to finish during hot-reloads # Can be provided in a format supported by Go's time.ParseDuration function or
# as raw values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 10 # Default: "10s"
# #
# graceTimeOut = 10 # graceTimeOut = "10s"
# Enable debug mode # Enable debug mode
# #
@ -47,11 +49,14 @@
# Backends throttle duration: minimum duration in seconds between 2 events from providers # Backends throttle duration: minimum duration in seconds between 2 events from providers
# before applying a new configuration. It avoids unnecessary reloads if multiples events # before applying a new configuration. It avoids unnecessary reloads if multiples events
# are sent in a short amount of time. # are sent in a short amount of time.
# Can be provided in a format supported by Go's time.ParseDuration function or
# as raw values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: "2" # Default: "2s"
# #
# ProvidersThrottleDuration = "5" # ProvidersThrottleDuration = "5s"
# If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. # If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
# If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value. # If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value.
@ -557,12 +562,15 @@
# groupsAsSubDomains = true # groupsAsSubDomains = true
# Override DialerTimeout # Override DialerTimeout
# Amount of time in seconds to allow the Marathon provider to wait to open a TCP # Amount of time to allow the Marathon provider to wait to open a TCP connection
# connection to a Marathon master # to a Marathon master.
# Can be provided in a format supported by Go's time.ParseDuration function or
# as raw values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 60 # Default: "60s"
# dialerTimeout = 5 # dialerTimeout = "60s"
# Enable Marathon basic authentication # Enable Marathon basic authentication
# #
@ -579,12 +587,15 @@
# dcosToken = "xxxxxx" # dcosToken = "xxxxxx"
# Set the TCP Keep Alive interval (in seconds) for the Marathon HTTP Client # Set the TCP Keep Alive interval for the Marathon HTTP Client.
# Can be provided in a format supported by Go's time.ParseDuration function or
# as raw values (digits). If no units are provided, the value is parsed assuming
# seconds.
# #
# Optional # Optional
# Default: 10 # Default: "10s"
# #
# keepAlive = 10 # keepAlive = "10s"
################################################################ ################################################################
# Mesos configuration backend # Mesos configuration backend