mirror of https://github.com/tidwall/tile38.git
Moved ReadMemStats into a background polling function
This will keep profile commands such as SERVER and STATS from stopping the world.
This commit is contained in:
commit
4bd6b4b838
|
@ -9,6 +9,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/resp"
|
"github.com/tidwall/resp"
|
||||||
|
@ -16,6 +17,30 @@ import (
|
||||||
"github.com/tidwall/tile38/internal/collection"
|
"github.com/tidwall/tile38/internal/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var memStats runtime.MemStats
|
||||||
|
var memStatsMu sync.Mutex
|
||||||
|
var memStatsBG bool
|
||||||
|
|
||||||
|
// ReadMemStats returns the latest memstats. It provides an instant response.
|
||||||
|
func readMemStats() runtime.MemStats {
|
||||||
|
memStatsMu.Lock()
|
||||||
|
if !memStatsBG {
|
||||||
|
runtime.ReadMemStats(&memStats)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
memStatsMu.Lock()
|
||||||
|
runtime.ReadMemStats(&memStats)
|
||||||
|
memStatsMu.Unlock()
|
||||||
|
time.Sleep(time.Second / 5)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
memStatsBG = true
|
||||||
|
}
|
||||||
|
ms := memStats
|
||||||
|
memStatsMu.Unlock()
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Server) cmdStats(msg *Message) (res resp.Value, err error) {
|
func (c *Server) cmdStats(msg *Message) (res resp.Value, err error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
vs := msg.Args[1:]
|
vs := msg.Args[1:]
|
||||||
|
@ -133,8 +158,7 @@ func (c *Server) basicStats(m map[string]interface{}) {
|
||||||
m["num_points"] = points
|
m["num_points"] = points
|
||||||
m["num_objects"] = objects
|
m["num_objects"] = objects
|
||||||
m["num_strings"] = strings
|
m["num_strings"] = strings
|
||||||
var mem runtime.MemStats
|
mem := readMemStats()
|
||||||
runtime.ReadMemStats(&mem)
|
|
||||||
avgsz := 0
|
avgsz := 0
|
||||||
if points != 0 {
|
if points != 0 {
|
||||||
avgsz = int(mem.HeapAlloc) / points
|
avgsz = int(mem.HeapAlloc) / points
|
||||||
|
@ -154,9 +178,8 @@ func (c *Server) basicStats(m map[string]interface{}) {
|
||||||
|
|
||||||
// extStats populates the passed map with extended system/go/tile38 statistics
|
// extStats populates the passed map with extended system/go/tile38 statistics
|
||||||
func (c *Server) extStats(m map[string]interface{}) {
|
func (c *Server) extStats(m map[string]interface{}) {
|
||||||
var mem runtime.MemStats
|
|
||||||
n, _ := runtime.ThreadCreateProfile(nil)
|
n, _ := runtime.ThreadCreateProfile(nil)
|
||||||
runtime.ReadMemStats(&mem)
|
mem := readMemStats()
|
||||||
|
|
||||||
// Go/Memory Stats
|
// Go/Memory Stats
|
||||||
|
|
||||||
|
@ -326,8 +349,7 @@ func (c *Server) writeInfoClients(w *bytes.Buffer) {
|
||||||
c.connsmu.RUnlock()
|
c.connsmu.RUnlock()
|
||||||
}
|
}
|
||||||
func (c *Server) writeInfoMemory(w *bytes.Buffer) {
|
func (c *Server) writeInfoMemory(w *bytes.Buffer) {
|
||||||
var mem runtime.MemStats
|
mem := readMemStats()
|
||||||
runtime.ReadMemStats(&mem)
|
|
||||||
fmt.Fprintf(w, "used_memory:%d\r\n", mem.Alloc) // total number of bytes allocated by Redis using its allocator (either standard libc, jemalloc, or an alternative allocator such as tcmalloc
|
fmt.Fprintf(w, "used_memory:%d\r\n", mem.Alloc) // total number of bytes allocated by Redis using its allocator (either standard libc, jemalloc, or an alternative allocator such as tcmalloc
|
||||||
}
|
}
|
||||||
func boolInt(t bool) int {
|
func boolInt(t bool) int {
|
||||||
|
|
Loading…
Reference in New Issue