mirror of https://github.com/tidwall/tile38.git
Merge branch 'm1ome-gc-config'
This commit is contained in:
commit
4d36e359ff
|
@ -14,7 +14,15 @@ import (
|
||||||
"github.com/tidwall/tile38/controller/server"
|
"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
|
// Config is a tile38 config
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -34,6 +42,8 @@ type Config struct {
|
||||||
ProtectedMode string `json:"-"`
|
ProtectedMode string `json:"-"`
|
||||||
MaxMemoryP string `json:"maxmemory,omitempty"`
|
MaxMemoryP string `json:"maxmemory,omitempty"`
|
||||||
MaxMemory int `json:"-"`
|
MaxMemory int `json:"-"`
|
||||||
|
AutoGCP string `json:"autogc,omitempty"`
|
||||||
|
AutoGC uint64 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) loadConfig() error {
|
func (c *Controller) loadConfig() error {
|
||||||
|
@ -49,16 +59,19 @@ func (c *Controller) loadConfig() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// load properties
|
// 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
|
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
|
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
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -115,17 +128,27 @@ func (c *Controller) setConfigProperty(name, value string, fromLoad bool) error
|
||||||
switch name {
|
switch name {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unsupported CONFIG parameter: %s", name)
|
return fmt.Errorf("Unsupported CONFIG parameter: %s", name)
|
||||||
case "requirepass":
|
case RequirePass:
|
||||||
c.config.RequirePass = value
|
c.config.RequirePass = value
|
||||||
case "leaderauth":
|
case LeaderAuth:
|
||||||
c.config.LeaderAuth = value
|
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)
|
sz, ok := parseMemSize(value)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Invalid argument '%s' for CONFIG SET '%s'", value, name)
|
return fmt.Errorf("Invalid argument '%s' for CONFIG SET '%s'", value, name)
|
||||||
}
|
}
|
||||||
c.config.MaxMemory = sz
|
c.config.MaxMemory = sz
|
||||||
case "protected-mode":
|
case ProtectedMode:
|
||||||
switch strings.ToLower(value) {
|
switch strings.ToLower(value) {
|
||||||
case "":
|
case "":
|
||||||
if fromLoad {
|
if fromLoad {
|
||||||
|
@ -159,13 +182,15 @@ func (c *Controller) getConfigProperty(name string) string {
|
||||||
switch name {
|
switch name {
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
case "requirepass":
|
case AutoGC:
|
||||||
|
return strconv.FormatUint(c.config.AutoGC, 10)
|
||||||
|
case RequirePass:
|
||||||
return c.config.RequirePass
|
return c.config.RequirePass
|
||||||
case "leaderauth":
|
case LeaderAuth:
|
||||||
return c.config.LeaderAuth
|
return c.config.LeaderAuth
|
||||||
case "protected-mode":
|
case ProtectedMode:
|
||||||
return c.config.ProtectedMode
|
return c.config.ProtectedMode
|
||||||
case "maxmemory":
|
case MaxMemory:
|
||||||
return formatMemSize(c.config.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.LeaderAuthP = c.config.LeaderAuth
|
||||||
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)
|
||||||
}
|
}
|
||||||
var data []byte
|
var data []byte
|
||||||
data, err = json.MarshalIndent(c.config, "", "\t")
|
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
|
var value string
|
||||||
if vs, value, ok = tokenval(vs); !ok {
|
if vs, value, ok = tokenval(vs); !ok {
|
||||||
if strings.ToLower(name) != "requirepass" {
|
if strings.ToLower(name) != RequirePass {
|
||||||
return "", errInvalidNumberOfArguments
|
return "", errInvalidNumberOfArguments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ type Controller struct {
|
||||||
|
|
||||||
stopBackgroundExpiring bool
|
stopBackgroundExpiring bool
|
||||||
stopWatchingMemory bool
|
stopWatchingMemory bool
|
||||||
|
stopWatchingAutoGC bool
|
||||||
outOfMemory bool
|
outOfMemory bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,11 +179,13 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
|
||||||
}()
|
}()
|
||||||
go c.processLives()
|
go c.processLives()
|
||||||
go c.watchMemory()
|
go c.watchMemory()
|
||||||
|
go c.watchGC()
|
||||||
go c.backgroundExpiring()
|
go c.backgroundExpiring()
|
||||||
defer func() {
|
defer func() {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.stopBackgroundExpiring = true
|
c.stopBackgroundExpiring = true
|
||||||
c.stopWatchingMemory = true
|
c.stopWatchingMemory = true
|
||||||
|
c.stopWatchingAutoGC = true
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
handler := func(conn *server.Conn, msg *server.Message, rd *server.AnyReaderWriter, w io.Writer, websocket bool) error {
|
handler := func(conn *server.Conn, msg *server.Message, rd *server.AnyReaderWriter, w io.Writer, websocket bool) error {
|
||||||
|
@ -226,6 +229,47 @@ func ListenAndServeEx(host string, port int, dir string, ln *net.Listener, http
|
||||||
return server.ListenAndServe(host, port, protected, handler, opened, closed, ln, http)
|
return server.ListenAndServe(host, port, protected, handler, opened, closed, ln, http)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Controller) watchGC() {
|
||||||
|
t := time.NewTicker(time.Second)
|
||||||
|
defer t.Stop()
|
||||||
|
|
||||||
|
s := time.Now()
|
||||||
|
for range t.C {
|
||||||
|
c.mu.RLock()
|
||||||
|
|
||||||
|
if c.stopWatchingAutoGC {
|
||||||
|
c.mu.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
autoGC := c.config.AutoGC
|
||||||
|
c.mu.RUnlock()
|
||||||
|
|
||||||
|
if autoGC == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if time.Now().Sub(s) < time.Second*time.Duration(autoGC) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var mem1, mem2 runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&mem1)
|
||||||
|
log.Debugf("autogc(before): "+
|
||||||
|
"alloc: %v, heap_alloc: %v, heap_released: %v",
|
||||||
|
mem1.Alloc, mem1.HeapAlloc, mem1.HeapReleased)
|
||||||
|
|
||||||
|
runtime.GC()
|
||||||
|
debug.FreeOSMemory()
|
||||||
|
|
||||||
|
runtime.ReadMemStats(&mem2)
|
||||||
|
log.Debugf("autogc(after): "+
|
||||||
|
"alloc: %v, heap_alloc: %v, heap_released: %v",
|
||||||
|
mem2.Alloc, mem2.HeapAlloc, mem2.HeapReleased)
|
||||||
|
s = time.Now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Controller) watchMemory() {
|
func (c *Controller) watchMemory() {
|
||||||
t := time.NewTicker(time.Second * 2)
|
t := time.NewTicker(time.Second * 2)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
|
|
Loading…
Reference in New Issue