mirror of https://github.com/tidwall/tile38.git
TCP Keepalives
Enabled TCP keepalive packets to determine if the connection is still valid, and terminate if needed. It also helps with maintaining idle connections. Default to 300 seconds and can be changed by: CONFIG SET keepalive 300 addresses #145: clients not being cleaned up properly
This commit is contained in:
parent
9a37f33a2c
commit
56e0bac24c
|
@ -20,9 +20,10 @@ const (
|
||||||
ProtectedMode = "protected-mode"
|
ProtectedMode = "protected-mode"
|
||||||
MaxMemory = "maxmemory"
|
MaxMemory = "maxmemory"
|
||||||
AutoGC = "autogc"
|
AutoGC = "autogc"
|
||||||
|
KeepAlive = "keepalive"
|
||||||
)
|
)
|
||||||
|
|
||||||
var validProperties = []string{RequirePass, LeaderAuth, ProtectedMode, MaxMemory, AutoGC}
|
var validProperties = []string{RequirePass, LeaderAuth, ProtectedMode, MaxMemory, AutoGC, KeepAlive}
|
||||||
|
|
||||||
// Config is a tile38 config
|
// Config is a tile38 config
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -44,6 +45,8 @@ type Config struct {
|
||||||
MaxMemory int `json:"-"`
|
MaxMemory int `json:"-"`
|
||||||
AutoGCP string `json:"autogc,omitempty"`
|
AutoGCP string `json:"autogc,omitempty"`
|
||||||
AutoGC uint64 `json:"-"`
|
AutoGC uint64 `json:"-"`
|
||||||
|
KeepAliveP string `json:"keepalive,omitempty"`
|
||||||
|
KeepAlive int `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) loadConfig() error {
|
func (c *Controller) loadConfig() error {
|
||||||
|
@ -74,6 +77,9 @@ func (c *Controller) loadConfig() error {
|
||||||
if err := c.setConfigProperty(AutoGC, c.config.AutoGCP, true); err != nil {
|
if err := c.setConfigProperty(AutoGC, c.config.AutoGCP, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := c.setConfigProperty(KeepAlive, c.config.KeepAliveP, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +167,19 @@ func (c *Controller) setConfigProperty(name, value string, fromLoad bool) error
|
||||||
default:
|
default:
|
||||||
invalid = true
|
invalid = true
|
||||||
}
|
}
|
||||||
|
case KeepAlive:
|
||||||
|
if value == "" {
|
||||||
|
c.config.KeepAlive = 300
|
||||||
|
} else {
|
||||||
|
keepalive, err := strconv.ParseUint(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
invalid = true
|
||||||
|
} else {
|
||||||
|
c.config.KeepAlive = int(keepalive)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if invalid {
|
if invalid {
|
||||||
return fmt.Errorf("Invalid argument '%s' for CONFIG SET '%s'", value, name)
|
return fmt.Errorf("Invalid argument '%s' for CONFIG SET '%s'", value, name)
|
||||||
}
|
}
|
||||||
|
@ -192,6 +210,8 @@ func (c *Controller) getConfigProperty(name string) string {
|
||||||
return c.config.ProtectedMode
|
return c.config.ProtectedMode
|
||||||
case MaxMemory:
|
case MaxMemory:
|
||||||
return formatMemSize(c.config.MaxMemory)
|
return formatMemSize(c.config.MaxMemory)
|
||||||
|
case KeepAlive:
|
||||||
|
return strconv.FormatUint(uint64(c.config.KeepAlive), 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +236,7 @@ func (c *Controller) writeConfig(writeProperties bool) error {
|
||||||
c.config.ProtectedModeP = c.config.ProtectedMode
|
c.config.ProtectedModeP = c.config.ProtectedMode
|
||||||
c.config.MaxMemoryP = formatMemSize(c.config.MaxMemory)
|
c.config.MaxMemoryP = formatMemSize(c.config.MaxMemory)
|
||||||
c.config.AutoGCP = strconv.FormatUint(c.config.AutoGC, 10)
|
c.config.AutoGCP = strconv.FormatUint(c.config.AutoGC, 10)
|
||||||
|
c.config.KeepAliveP = strconv.FormatUint(uint64(c.config.KeepAlive), 10)
|
||||||
}
|
}
|
||||||
var data []byte
|
var data []byte
|
||||||
data, err = json.MarshalIndent(c.config, "", "\t")
|
data, err = json.MarshalIndent(c.config, "", "\t")
|
||||||
|
|
|
@ -227,8 +227,17 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
|
||||||
return is
|
return is
|
||||||
}
|
}
|
||||||
var clientId uint64
|
var clientId uint64
|
||||||
|
|
||||||
opened := func(conn *server.Conn) {
|
opened := func(conn *server.Conn) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
|
if c.config.KeepAlive > 0 {
|
||||||
|
err := conn.SetKeepAlive(
|
||||||
|
time.Duration(c.config.KeepAlive) * time.Second)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("could not set keepalive for connection: %v",
|
||||||
|
conn.RemoteAddr().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
clientId++
|
clientId++
|
||||||
c.conns[conn] = &clientConn{
|
c.conns[conn] = &clientConn{
|
||||||
id: clientId,
|
id: clientId,
|
||||||
|
|
|
@ -45,6 +45,16 @@ type Conn struct {
|
||||||
Authenticated bool
|
Authenticated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (conn Conn) SetKeepAlive(period time.Duration) error {
|
||||||
|
if tcp, ok := conn.Conn.(*net.TCPConn); ok {
|
||||||
|
if err := tcp.SetKeepAlive(true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tcp.SetKeepAlivePeriod(period)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var errCloseHTTP = errors.New("close http")
|
var errCloseHTTP = errors.New("close http")
|
||||||
|
|
||||||
// ListenAndServe starts a tile38 server at the specified address.
|
// ListenAndServe starts a tile38 server at the specified address.
|
||||||
|
|
Loading…
Reference in New Issue