mirror of https://github.com/tidwall/tile38.git
Implementing autogc configuration support
This commit is contained in:
parent
8a8a526e40
commit
e65e5842f4
|
@ -14,7 +14,15 @@ import (
|
|||
"github.com/tidwall/tile38/controller/server"
|
||||
)
|
||||
|
||||
var validProperties = []string{"requirepass", "leaderauth", "protected-mode", "maxmemory"}
|
||||
const (
|
||||
RequirePass = "requirepass"
|
||||
LeaderAuth = "leaderauth"
|
||||
ProtectedMode = "protected-mode"
|
||||
MaxMemory = "maxmemory"
|
||||
AutoGC = "autogc"
|
||||
)
|
||||
|
||||
var validProperties = []string{RequirePass, LeaderAuth, ProtectedMode, MaxMemory, AutoGC}
|
||||
|
||||
// Config is a tile38 config
|
||||
type Config struct {
|
||||
|
@ -34,6 +42,8 @@ type Config struct {
|
|||
ProtectedMode string `json:"-"`
|
||||
MaxMemoryP string `json:"maxmemory,omitempty"`
|
||||
MaxMemory int `json:"-"`
|
||||
AutoGCP string `json:"autogc,omitempty"`
|
||||
AutoGC uint64 `json:"-"`
|
||||
}
|
||||
|
||||
func (c *Controller) loadConfig() error {
|
||||
|
@ -49,16 +59,19 @@ func (c *Controller) loadConfig() error {
|
|||
return err
|
||||
}
|
||||
// load properties
|
||||
if err := c.setConfigProperty("requirepass", c.config.RequirePassP, true); err != nil {
|
||||
if err := c.setConfigProperty(RequirePass, c.config.RequirePassP, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.setConfigProperty("leaderauth", c.config.LeaderAuthP, true); err != nil {
|
||||
if err := c.setConfigProperty(LeaderAuth, c.config.LeaderAuthP, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.setConfigProperty("protected-mode", c.config.ProtectedModeP, true); err != nil {
|
||||
if err := c.setConfigProperty(ProtectedMode, c.config.ProtectedModeP, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.setConfigProperty("maxmemory", c.config.MaxMemoryP, true); err != nil {
|
||||
if err := c.setConfigProperty(MaxMemory, c.config.MaxMemoryP, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.setConfigProperty(AutoGC, c.config.AutoGCP, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -115,17 +128,27 @@ func (c *Controller) setConfigProperty(name, value string, fromLoad bool) error
|
|||
switch name {
|
||||
default:
|
||||
return fmt.Errorf("Unsupported CONFIG parameter: %s", name)
|
||||
case "requirepass":
|
||||
case RequirePass:
|
||||
c.config.RequirePass = value
|
||||
case "leaderauth":
|
||||
case LeaderAuth:
|
||||
c.config.LeaderAuth = value
|
||||
case "maxmemory":
|
||||
case AutoGC:
|
||||
if value == "" {
|
||||
c.config.AutoGC = 0
|
||||
} else {
|
||||
gc, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.config.AutoGC = gc
|
||||
}
|
||||
case MaxMemory:
|
||||
sz, ok := parseMemSize(value)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid argument '%s' for CONFIG SET '%s'", value, name)
|
||||
}
|
||||
c.config.MaxMemory = sz
|
||||
case "protected-mode":
|
||||
case ProtectedMode:
|
||||
switch strings.ToLower(value) {
|
||||
case "":
|
||||
if fromLoad {
|
||||
|
@ -159,13 +182,15 @@ func (c *Controller) getConfigProperty(name string) string {
|
|||
switch name {
|
||||
default:
|
||||
return ""
|
||||
case "requirepass":
|
||||
case AutoGC:
|
||||
return strconv.FormatUint(c.config.AutoGC, 10)
|
||||
case RequirePass:
|
||||
return c.config.RequirePass
|
||||
case "leaderauth":
|
||||
case LeaderAuth:
|
||||
return c.config.LeaderAuth
|
||||
case "protected-mode":
|
||||
case ProtectedMode:
|
||||
return c.config.ProtectedMode
|
||||
case "maxmemory":
|
||||
case MaxMemory:
|
||||
return formatMemSize(c.config.MaxMemory)
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +215,7 @@ func (c *Controller) writeConfig(writeProperties bool) error {
|
|||
c.config.LeaderAuthP = c.config.LeaderAuth
|
||||
c.config.ProtectedModeP = c.config.ProtectedMode
|
||||
c.config.MaxMemoryP = formatMemSize(c.config.MaxMemory)
|
||||
c.config.AutoGCP = strconv.FormatUint(c.config.AutoGC, 10)
|
||||
}
|
||||
var data []byte
|
||||
data, err = json.MarshalIndent(c.config, "", "\t")
|
||||
|
@ -242,7 +268,7 @@ func (c *Controller) cmdConfigSet(msg *server.Message) (res string, err error) {
|
|||
}
|
||||
var value string
|
||||
if vs, value, ok = tokenval(vs); !ok {
|
||||
if strings.ToLower(name) != "requirepass" {
|
||||
if strings.ToLower(name) != RequirePass {
|
||||
return "", errInvalidNumberOfArguments
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ type Controller struct {
|
|||
|
||||
stopBackgroundExpiring bool
|
||||
stopWatchingMemory bool
|
||||
stopWatchingAutoGC bool
|
||||
outOfMemory bool
|
||||
}
|
||||
|
||||
|
@ -178,11 +179,13 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
|
|||
}()
|
||||
go c.processLives()
|
||||
go c.watchMemory()
|
||||
go c.watchGC()
|
||||
go c.backgroundExpiring()
|
||||
defer func() {
|
||||
c.mu.Lock()
|
||||
c.stopBackgroundExpiring = true
|
||||
c.stopWatchingMemory = true
|
||||
c.stopWatchingAutoGC = true
|
||||
c.mu.Unlock()
|
||||
}()
|
||||
handler := func(conn *server.Conn, msg *server.Message, rd *server.AnyReaderWriter, w io.Writer, websocket bool) error {
|
||||
|
@ -226,6 +229,30 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
|
|||
return server.ListenAndServe(host, port, protected, handler, opened, closed, ln, http)
|
||||
}
|
||||
|
||||
func (c *Controller) watchGC() {
|
||||
autoGC := c.config.AutoGC
|
||||
|
||||
if autoGC == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
t := time.NewTicker(time.Second * time.Duration(autoGC))
|
||||
defer t.Stop()
|
||||
|
||||
for range t.C {
|
||||
func() {
|
||||
c.mu.RLock()
|
||||
if c.stopWatchingAutoGC {
|
||||
c.mu.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
debug.FreeOSMemory()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) watchMemory() {
|
||||
t := time.NewTicker(time.Second * 2)
|
||||
defer t.Stop()
|
||||
|
|
Loading…
Reference in New Issue