Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 3 additions & 29 deletions cmd/daze/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"encoding/json"
"expvar"
"flag"
"fmt"
"log"
Expand All @@ -16,6 +14,7 @@ import (

"github.com/libraries/daze"
"github.com/libraries/daze/lib/doa"
"github.com/libraries/daze/lib/expvpp"
"github.com/libraries/daze/lib/gracefulexit"
"github.com/libraries/daze/lib/rate"
"github.com/libraries/daze/protocol/ashe"
Expand Down Expand Up @@ -63,31 +62,6 @@ func main() {
if os.Getenv("ANDROID_ROOT") != "" {
net.DefaultResolver = daze.ResolverDns(daze.ResolverPublic.Cloudflare.Dns)
}
// Remove cmdline and memstats from expvar default exports.
// See: https://github.com/golang/go/issues/29105
muxHttp := http.NewServeMux()
muxHttp.HandleFunc("/debug/vars", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
vars := new(expvar.Map).Init()
expvar.Do(func(kv expvar.KeyValue) {
vars.Set(kv.Key, kv.Value)
})
vars.Delete("cmdline")
vars.Delete("memstats")
msg := map[string]any{}
err := json.Unmarshal([]byte(vars.String()), &msg)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
enc.Encode(msg)
})
muxHttp.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.DefaultServeMux.ServeHTTP(w, r)
})
resExec := filepath.Dir(doa.Try(os.Executable()))
subCommand := os.Args[1]
os.Args = os.Args[1:len(os.Args)]
Expand Down Expand Up @@ -148,7 +122,7 @@ func main() {
if *flGpprof != "" {
_ = pprof.Handler
log.Println("main: listen net/http/pprof on", *flGpprof)
go func() { doa.Nil(http.ListenAndServe(*flGpprof, muxHttp)) }()
go func() { doa.Nil(http.ListenAndServe(*flGpprof, expvpp.ServeMux())) }()
}
// Hang prevent program from exiting.
gracefulexit.Wait()
Expand Down Expand Up @@ -226,7 +200,7 @@ func main() {
if *flGpprof != "" {
_ = pprof.Handler
log.Println("main: listen net/http/pprof on", *flGpprof)
go func() { doa.Nil(http.ListenAndServe(*flGpprof, muxHttp)) }()
go func() { doa.Nil(http.ListenAndServe(*flGpprof, expvpp.ServeMux())) }()
}
// Hang prevent program from exiting.
gracefulexit.Wait()
Expand Down
40 changes: 5 additions & 35 deletions daze.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"time"

"github.com/libraries/daze/lib/doa"
"github.com/libraries/daze/lib/expvpp"
"github.com/libraries/daze/lib/lru"
"github.com/libraries/daze/lib/pretty"
"github.com/libraries/daze/lib/rate"
Expand Down Expand Up @@ -66,15 +67,15 @@ var Conf = struct {
var Expv = struct {
RouterCacheCall *expvar.Int
RouterCacheHits *expvar.Int
RouterCacheRate expvar.Func
RouterCacheRate *expvar.Func
RouterIPNetCall *expvar.Int
RouterIPNetTime *ExpvarAverage
RouterIPNetTime *expvpp.ExpvarAverage
}{
RouterCacheCall: expvar.NewInt("RouterCache.Call"),
RouterCacheHits: expvar.NewInt("RouterCache.Hits"),
RouterCacheRate: NewExpvarPercent("RouterCache.Rate", "RouterCache.Hits", "RouterCache.Call"),
RouterCacheRate: expvpp.NewExpvarPercent("RouterCache.Rate", "RouterCache.Hits", "RouterCache.Call"),
RouterIPNetCall: expvar.NewInt("RouterIPNet.Call"),
RouterIPNetTime: NewExpvarAverage("RouterIPNet.Time", 64),
RouterIPNetTime: expvpp.NewExpvarAverage("RouterIPNet.Time", 64),
}

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

// ExpvarAverage is a structure to maintain a running average using expvar.Float.
type ExpvarAverage struct {
F *expvar.Float
L float64
}

// Adds a new value to the running average. This is not strictly concurrency-safe, but it won't have much impact on the
// data.
func (e *ExpvarAverage) Add(value float64) {
e.F.Add((value - e.F.Value()) / e.L)
}

// NewExpvarAverage creates and initializes a new ExpvarAverage instance.
func NewExpvarAverage(name string, length int) *ExpvarAverage {
return &ExpvarAverage{
F: expvar.NewFloat(name),
L: float64(length),
}
}

// NewExpvarPercent creates a new expvar.Func that calculates the ratio of two expvar.Int or expvar.Float metrics.
func NewExpvarPercent(name string, n string, d string) expvar.Func {
f := expvar.Func(func() any {
v := doa.Try(strconv.ParseFloat(expvar.Get(n).String(), 64))
w := doa.Try(strconv.ParseFloat(expvar.Get(d).String(), 64))
return float64(v) / float64(max(1, w))
})
expvar.Publish(name, f)
return f
}

// GravityReader wraps an io.Reader with RC4 crypto.
func GravityReader(r io.Reader, k []byte) io.Reader {
cr := doa.Try(rc4.NewCipher(k))
Expand Down
68 changes: 68 additions & 0 deletions lib/expvpp/expvpp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package expvpp

import (
"encoding/json"
"expvar"
"net/http"
"strconv"
)

// ExpvarAverage is a structure to maintain a running average using expvar.Float.
type ExpvarAverage struct {
F *expvar.Float
L float64
}

// Adds a new value to the running average. This is not strictly concurrency-safe, but it won't have much impact on the
// data.
func (e *ExpvarAverage) Add(value float64) {
e.F.Add((value - e.F.Value()) / e.L)
}

// NewExpvarAverage creates and initializes a new ExpvarAverage instance.
func NewExpvarAverage(name string, length int) *ExpvarAverage {
return &ExpvarAverage{
F: expvar.NewFloat(name),
L: float64(length),
}
}

// NewExpvarPercent creates a new expvar.Func that calculates the ratio of two expvar.Int or expvar.Float metrics.
func NewExpvarPercent(name string, n string, d string) *expvar.Func {
f := expvar.Func(func() any {
v, _ := strconv.ParseFloat(expvar.Get(n).String(), 64)
w, _ := strconv.ParseFloat(expvar.Get(d).String(), 64)
return float64(v) / float64(max(1, w))
})
expvar.Publish(name, f)
return &f
}

// ServeMux returns a new http.ServeMux that removes cmdline and memstats from expvar default exports.
// See: https://github.com/golang/go/issues/29105
func ServeMux() *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/debug/vars", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
vars := new(expvar.Map).Init()
expvar.Do(func(kv expvar.KeyValue) {
vars.Set(kv.Key, kv.Value)
})
vars.Delete("cmdline")
vars.Delete("memstats")
msg := map[string]any{}
err := json.Unmarshal([]byte(vars.String()), &msg)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
enc.Encode(msg)
})
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.DefaultServeMux.ServeHTTP(w, r)
})
return mux
}
5 changes: 3 additions & 2 deletions protocol/ashe/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/libraries/daze"
"github.com/libraries/daze/lib/doa"
"github.com/libraries/daze/lib/expvpp"
"github.com/libraries/daze/lib/rate"
)

Expand Down Expand Up @@ -56,9 +57,9 @@ var Conf = struct {

// Expv is a simple wrapper around the expvars package.
var Expv = struct {
ServerClockSkew *daze.ExpvarAverage
ServerClockSkew *expvpp.ExpvarAverage
}{
ServerClockSkew: daze.NewExpvarAverage("Protocol.Ashe.Server.ClockSkew", 64),
ServerClockSkew: expvpp.NewExpvarAverage("Protocol.Ashe.Server.ClockSkew", 64),
}

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