feat: measure each direction of the speed test for 7 s (0.0.7)
This commit is contained in:
1 parent
ab8751d436
commit
5155bc36cd
5 files changed
+32
-21
No files matched your search
+17
-11
@@ -13,24 +13,30 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// speedWindow is how long each direction is measured for.
|
||||
speedWindow = 3 * time.Second
|
||||
// speedWindow is how long each direction is measured for, unless the
|
||||
// server asks for another window; speedWindowMax bounds what it may ask.
|
||||
speedWindow = 3 * time.Second
|
||||
speedWindowMax = 30 * time.Second
|
||||
// speedWait is how long the download may take to start: in a relayed test
|
||||
// its bytes come from the browser.
|
||||
speedWait = 10 * time.Second
|
||||
// speedUpCap bounds the upload, whatever the link does in speedWindow.
|
||||
// speedUpCap bounds the upload, whatever the link does in the window.
|
||||
speedUpCap = 48 << 20
|
||||
)
|
||||
|
||||
// doSpeed measures the agent's HTTP link to the server: round-trip time of an
|
||||
// empty request, then how much flows each way in speedWindow. In a relayed
|
||||
// empty request, then how much flows each way in the window. In a relayed
|
||||
// test the server pipes both streams to the browser, so they run end to end.
|
||||
func (a *Agent) doSpeed(ctx context.Context, env proto.TaskEnvelope) proto.TaskResult {
|
||||
var args proto.SysSpeedArgs
|
||||
if len(env.Args) > 0 {
|
||||
_ = json.Unmarshal(env.Args, &args)
|
||||
}
|
||||
res, err := a.measureSpeed(ctx, args.Relay)
|
||||
window := speedWindow
|
||||
if args.WindowMs > 0 {
|
||||
window = min(time.Duration(args.WindowMs)*time.Millisecond, speedWindowMax)
|
||||
}
|
||||
res, err := a.measureSpeed(ctx, args.Relay, window)
|
||||
if err != nil {
|
||||
return proto.TaskResult{Error: err.Error()}
|
||||
}
|
||||
@@ -38,7 +44,7 @@ func (a *Agent) doSpeed(ctx context.Context, env proto.TaskEnvelope) proto.TaskR
|
||||
return proto.TaskResult{OK: true, Data: data}
|
||||
}
|
||||
|
||||
func (a *Agent) measureSpeed(ctx context.Context, relay bool) (proto.SysSpeedResult, error) {
|
||||
func (a *Agent) measureSpeed(ctx context.Context, relay bool, window time.Duration) (proto.SysSpeedResult, error) {
|
||||
res := proto.SysSpeedResult{Relay: relay}
|
||||
streams := "/api/agent/speed"
|
||||
if relay {
|
||||
@@ -59,14 +65,14 @@ func (a *Agent) measureSpeed(ctx context.Context, relay bool) (proto.SysSpeedRes
|
||||
}
|
||||
}
|
||||
|
||||
down, err := a.speedDown(ctx, streams+"/down")
|
||||
down, err := a.speedDown(ctx, streams+"/down", window)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.DownBps = down
|
||||
|
||||
// Up: send until the window closes or the cap is hit.
|
||||
body := &speedSource{deadline: time.Now().Add(speedWindow), left: speedUpCap}
|
||||
body := &speedSource{deadline: time.Now().Add(window), left: speedUpCap}
|
||||
start := time.Now()
|
||||
resp, err := a.speedRequest(ctx, http.MethodPost, streams+"/up", body)
|
||||
if err != nil {
|
||||
@@ -78,9 +84,9 @@ func (a *Agent) measureSpeed(ctx context.Context, relay bool) (proto.SysSpeedRes
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// speedDown reads what the server streams for speedWindow, counted from the
|
||||
// speedDown reads what the server streams for the window, counted from the
|
||||
// first byte, and returns the rate.
|
||||
func (a *Agent) speedDown(ctx context.Context, path string) (float64, error) {
|
||||
func (a *Agent) speedDown(ctx context.Context, path string, window time.Duration) (float64, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
t := time.AfterFunc(speedWait, cancel)
|
||||
@@ -99,7 +105,7 @@ func (a *Agent) speedDown(ctx context.Context, path string) (float64, error) {
|
||||
k, err := resp.Body.Read(buf)
|
||||
if k > 0 && start.IsZero() {
|
||||
start = time.Now()
|
||||
t.Reset(speedWindow)
|
||||
t.Reset(window)
|
||||
}
|
||||
n += int64(k)
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user