From e1a4cbaf709c80e68ddfb3ae249420a24d3aab3e Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Wed, 28 Nov 2018 18:01:47 -0700 Subject: [PATCH] Update to LameDuck mode - Increase grace period to 10sec - Make default 2min - Reject config with value less than 30sec - Don't wait more than 1sec between clients if there are much less than alloted time - Stop after last one (was still sleeping after last client was closed) Signed-off-by: Ivan Kozlovic --- server/configs/test.conf | 2 +- server/const.go | 2 +- server/opts.go | 5 +++++ server/opts_test.go | 2 +- server/server.go | 11 ++++++++++- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/server/configs/test.conf b/server/configs/test.conf index 21e420eb..0eb6f309 100644 --- a/server/configs/test.conf +++ b/server/configs/test.conf @@ -45,4 +45,4 @@ ping_max: 3 # how long server can block on a socket write to a client write_deadline: "3s" -lame_duck_duration: "4s" \ No newline at end of file +lame_duck_duration: "4m" diff --git a/server/const.go b/server/const.go index 02d0fc2e..bcd9e558 100644 --- a/server/const.go +++ b/server/const.go @@ -135,5 +135,5 @@ const ( // DEFAULT_LAME_DUCK_DURATION is the time in which the server spreads // the closing of clients when signaled to go in lame duck mode. - DEFAULT_LAME_DUCK_DURATION = 30 * time.Second + DEFAULT_LAME_DUCK_DURATION = 2 * time.Minute ) diff --git a/server/opts.go b/server/opts.go index 1de1d118..6b577527 100644 --- a/server/opts.go +++ b/server/opts.go @@ -479,6 +479,11 @@ func (o *Options) ProcessConfigFile(configFile string) error { errors = append(errors, err) continue } + if dur < 30*time.Second { + err := &configErr{tk, fmt.Sprintf("invalid lame_duck_duration of %v, minimum is 30 seconds", dur)} + errors = append(errors, err) + continue + } o.LameDuckDuration = dur case "trusted": switch v.(type) { diff --git a/server/opts_test.go b/server/opts_test.go index fe210e50..77130d58 100644 --- a/server/opts_test.go +++ b/server/opts_test.go @@ -89,7 +89,7 @@ func TestConfigFile(t *testing.T) { PingInterval: 60 * time.Second, MaxPingsOut: 3, WriteDeadline: 3 * time.Second, - LameDuckDuration: 4 * time.Second, + LameDuckDuration: 4 * time.Minute, } opts, err := ProcessConfigFile("./configs/test.conf") diff --git a/server/server.go b/server/server.go index c5216e99..6adc6f0e 100644 --- a/server/server.go +++ b/server/server.go @@ -42,7 +42,7 @@ import ( ) // Time to wait before starting closing clients when in LD mode. -const lameDuckModeDefaultInitialDelay = int64(time.Second) +const lameDuckModeDefaultInitialDelay = int64(10 * time.Second) // Make this a variable so that we can change during tests var lameDuckModeInitialDelay = int64(lameDuckModeDefaultInitialDelay) @@ -1853,7 +1853,13 @@ func (s *Server) lameDuckMode() { // use a tiny sleep interval that will result in yield likely. si = 1 batch = int(numClients / dur) + } else if si > int64(time.Second) { + // Conversely, there is no need to sleep too long between clients + // and spread say 10 clients for the 2min duration. Sleeping no + // more than 1sec. + si = int64(time.Second) } + // Now capture all clients clients := make([]*client, 0, len(s.clients)) for _, client := range s.clients { @@ -1873,6 +1879,9 @@ func (s *Server) lameDuckMode() { } for i, client := range clients { client.closeConnection(ServerShutdown) + if i == len(clients)-1 { + break + } if batch == 1 || i%batch == 0 { // We pick a random interval which will be at least si/2 v := rand.Int63n(si)