Skip to content

Commit c7ca335

Browse files
authored
Refactor expvar
1 parent f4ac4e8 commit c7ca335

4 files changed

Lines changed: 79 additions & 66 deletions

File tree

cmd/daze/main.go

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package main
22

33
import (
4-
"encoding/json"
5-
"expvar"
64
"flag"
75
"fmt"
86
"log"
@@ -16,6 +14,7 @@ import (
1614

1715
"github.com/libraries/daze"
1816
"github.com/libraries/daze/lib/doa"
17+
"github.com/libraries/daze/lib/expvpp"
1918
"github.com/libraries/daze/lib/gracefulexit"
2019
"github.com/libraries/daze/lib/rate"
2120
"github.com/libraries/daze/protocol/ashe"
@@ -63,31 +62,6 @@ func main() {
6362
if os.Getenv("ANDROID_ROOT") != "" {
6463
net.DefaultResolver = daze.ResolverDns(daze.ResolverPublic.Cloudflare.Dns)
6564
}
66-
// Remove cmdline and memstats from expvar default exports.
67-
// See: https://github.com/golang/go/issues/29105
68-
muxHttp := http.NewServeMux()
69-
muxHttp.HandleFunc("/debug/vars", func(w http.ResponseWriter, r *http.Request) {
70-
w.Header().Set("Content-Type", "application/json; charset=utf-8")
71-
vars := new(expvar.Map).Init()
72-
expvar.Do(func(kv expvar.KeyValue) {
73-
vars.Set(kv.Key, kv.Value)
74-
})
75-
vars.Delete("cmdline")
76-
vars.Delete("memstats")
77-
msg := map[string]any{}
78-
err := json.Unmarshal([]byte(vars.String()), &msg)
79-
if err != nil {
80-
w.WriteHeader(http.StatusBadRequest)
81-
w.Write([]byte(err.Error()))
82-
return
83-
}
84-
enc := json.NewEncoder(w)
85-
enc.SetIndent("", " ")
86-
enc.Encode(msg)
87-
})
88-
muxHttp.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
89-
http.DefaultServeMux.ServeHTTP(w, r)
90-
})
9165
resExec := filepath.Dir(doa.Try(os.Executable()))
9266
subCommand := os.Args[1]
9367
os.Args = os.Args[1:len(os.Args)]
@@ -148,7 +122,7 @@ func main() {
148122
if *flGpprof != "" {
149123
_ = pprof.Handler
150124
log.Println("main: listen net/http/pprof on", *flGpprof)
151-
go func() { doa.Nil(http.ListenAndServe(*flGpprof, muxHttp)) }()
125+
go func() { doa.Nil(http.ListenAndServe(*flGpprof, expvpp.ServeMux())) }()
152126
}
153127
// Hang prevent program from exiting.
154128
gracefulexit.Wait()
@@ -226,7 +200,7 @@ func main() {
226200
if *flGpprof != "" {
227201
_ = pprof.Handler
228202
log.Println("main: listen net/http/pprof on", *flGpprof)
229-
go func() { doa.Nil(http.ListenAndServe(*flGpprof, muxHttp)) }()
203+
go func() { doa.Nil(http.ListenAndServe(*flGpprof, expvpp.ServeMux())) }()
230204
}
231205
// Hang prevent program from exiting.
232206
gracefulexit.Wait()

daze.go

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"time"
2929

3030
"github.com/libraries/daze/lib/doa"
31+
"github.com/libraries/daze/lib/expvpp"
3132
"github.com/libraries/daze/lib/lru"
3233
"github.com/libraries/daze/lib/pretty"
3334
"github.com/libraries/daze/lib/rate"
@@ -66,15 +67,15 @@ var Conf = struct {
6667
var Expv = struct {
6768
RouterCacheCall *expvar.Int
6869
RouterCacheHits *expvar.Int
69-
RouterCacheRate expvar.Func
70+
RouterCacheRate *expvar.Func
7071
RouterIPNetCall *expvar.Int
71-
RouterIPNetTime *ExpvarAverage
72+
RouterIPNetTime *expvpp.ExpvarAverage
7273
}{
7374
RouterCacheCall: expvar.NewInt("RouterCache.Call"),
7475
RouterCacheHits: expvar.NewInt("RouterCache.Hits"),
75-
RouterCacheRate: NewExpvarPercent("RouterCache.Rate", "RouterCache.Hits", "RouterCache.Call"),
76+
RouterCacheRate: expvpp.NewExpvarPercent("RouterCache.Rate", "RouterCache.Hits", "RouterCache.Call"),
7677
RouterIPNetCall: expvar.NewInt("RouterIPNet.Call"),
77-
RouterIPNetTime: NewExpvarAverage("RouterIPNet.Time", 64),
78+
RouterIPNetTime: expvpp.NewExpvarAverage("RouterIPNet.Time", 64),
7879
}
7980

8081
// ResolverDns returns a DNS resolver.
@@ -1059,37 +1060,6 @@ func Dial(network string, address string) (net.Conn, error) {
10591060
return d.Dial(network, address)
10601061
}
10611062

1062-
// ExpvarAverage is a structure to maintain a running average using expvar.Float.
1063-
type ExpvarAverage struct {
1064-
F *expvar.Float
1065-
L float64
1066-
}
1067-
1068-
// Adds a new value to the running average. This is not strictly concurrency-safe, but it won't have much impact on the
1069-
// data.
1070-
func (e *ExpvarAverage) Add(value float64) {
1071-
e.F.Add((value - e.F.Value()) / e.L)
1072-
}
1073-
1074-
// NewExpvarAverage creates and initializes a new ExpvarAverage instance.
1075-
func NewExpvarAverage(name string, length int) *ExpvarAverage {
1076-
return &ExpvarAverage{
1077-
F: expvar.NewFloat(name),
1078-
L: float64(length),
1079-
}
1080-
}
1081-
1082-
// NewExpvarPercent creates a new expvar.Func that calculates the ratio of two expvar.Int or expvar.Float metrics.
1083-
func NewExpvarPercent(name string, n string, d string) expvar.Func {
1084-
f := expvar.Func(func() any {
1085-
v := doa.Try(strconv.ParseFloat(expvar.Get(n).String(), 64))
1086-
w := doa.Try(strconv.ParseFloat(expvar.Get(d).String(), 64))
1087-
return float64(v) / float64(max(1, w))
1088-
})
1089-
expvar.Publish(name, f)
1090-
return f
1091-
}
1092-
10931063
// GravityReader wraps an io.Reader with RC4 crypto.
10941064
func GravityReader(r io.Reader, k []byte) io.Reader {
10951065
cr := doa.Try(rc4.NewCipher(k))

lib/expvpp/expvpp.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package expvpp
2+
3+
import (
4+
"encoding/json"
5+
"expvar"
6+
"net/http"
7+
"strconv"
8+
)
9+
10+
// ExpvarAverage is a structure to maintain a running average using expvar.Float.
11+
type ExpvarAverage struct {
12+
F *expvar.Float
13+
L float64
14+
}
15+
16+
// Adds a new value to the running average. This is not strictly concurrency-safe, but it won't have much impact on the
17+
// data.
18+
func (e *ExpvarAverage) Add(value float64) {
19+
e.F.Add((value - e.F.Value()) / e.L)
20+
}
21+
22+
// NewExpvarAverage creates and initializes a new ExpvarAverage instance.
23+
func NewExpvarAverage(name string, length int) *ExpvarAverage {
24+
return &ExpvarAverage{
25+
F: expvar.NewFloat(name),
26+
L: float64(length),
27+
}
28+
}
29+
30+
// NewExpvarPercent creates a new expvar.Func that calculates the ratio of two expvar.Int or expvar.Float metrics.
31+
func NewExpvarPercent(name string, n string, d string) *expvar.Func {
32+
f := expvar.Func(func() any {
33+
v, _ := strconv.ParseFloat(expvar.Get(n).String(), 64)
34+
w, _ := strconv.ParseFloat(expvar.Get(d).String(), 64)
35+
return float64(v) / float64(max(1, w))
36+
})
37+
expvar.Publish(name, f)
38+
return &f
39+
}
40+
41+
// ServeMux returns a new http.ServeMux that removes cmdline and memstats from expvar default exports.
42+
// See: https://github.com/golang/go/issues/29105
43+
func ServeMux() *http.ServeMux {
44+
mux := http.NewServeMux()
45+
mux.HandleFunc("/debug/vars", func(w http.ResponseWriter, r *http.Request) {
46+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
47+
vars := new(expvar.Map).Init()
48+
expvar.Do(func(kv expvar.KeyValue) {
49+
vars.Set(kv.Key, kv.Value)
50+
})
51+
vars.Delete("cmdline")
52+
vars.Delete("memstats")
53+
msg := map[string]any{}
54+
err := json.Unmarshal([]byte(vars.String()), &msg)
55+
if err != nil {
56+
w.WriteHeader(http.StatusBadRequest)
57+
w.Write([]byte(err.Error()))
58+
return
59+
}
60+
enc := json.NewEncoder(w)
61+
enc.SetIndent("", " ")
62+
enc.Encode(msg)
63+
})
64+
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
65+
http.DefaultServeMux.ServeHTTP(w, r)
66+
})
67+
return mux
68+
}

protocol/ashe/engine.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/libraries/daze"
1414
"github.com/libraries/daze/lib/doa"
15+
"github.com/libraries/daze/lib/expvpp"
1516
"github.com/libraries/daze/lib/rate"
1617
)
1718

@@ -56,9 +57,9 @@ var Conf = struct {
5657

5758
// Expv is a simple wrapper around the expvars package.
5859
var Expv = struct {
59-
ServerClockSkew *daze.ExpvarAverage
60+
ServerClockSkew *expvpp.ExpvarAverage
6061
}{
61-
ServerClockSkew: daze.NewExpvarAverage("Protocol.Ashe.Server.ClockSkew", 64),
62+
ServerClockSkew: expvpp.NewExpvarAverage("Protocol.Ashe.Server.ClockSkew", 64),
6263
}
6364

6465
// TCPConn is an implementation of the Conn interface for tcp network connections.

0 commit comments

Comments
 (0)