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 <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2018-11-28 18:01:47 -07:00
parent 7ef7fdfc23
commit e1a4cbaf70
5 changed files with 18 additions and 4 deletions

View File

@@ -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"
lame_duck_duration: "4m"

View File

@@ -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
)

View File

@@ -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) {

View File

@@ -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")

View File

@@ -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)