Record delay test history in proxy info (Clash API standard compliance)
This commit is contained in:
8
api.go
8
api.go
@@ -86,7 +86,7 @@ func (b *Box) buildProxyInfo(tag, outType string, group proxyGroup) map[string]a
|
||||
"type": capitalizeType(outType),
|
||||
"alive": true,
|
||||
"udp": true,
|
||||
"history": []map[string]any{},
|
||||
"history": b.getHistory(tag),
|
||||
}
|
||||
if group != nil {
|
||||
info["now"] = group.Now()
|
||||
@@ -394,13 +394,15 @@ func (b *Box) handleProxyDelay(w http.ResponseWriter, r *http.Request, name stri
|
||||
|
||||
delay, err := testProxyDelay(out, testURL, time.Duration(timeoutMs)*time.Millisecond)
|
||||
if err != nil {
|
||||
b.recordDelay(name, 0)
|
||||
writeJSON(w, map[string]any{
|
||||
"name": name,
|
||||
"delay": 0,
|
||||
"name": name,
|
||||
"delay": 0,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
b.recordDelay(name, delay)
|
||||
writeJSON(w, map[string]any{
|
||||
"name": name,
|
||||
"delay": delay,
|
||||
|
||||
40
box.go
40
box.go
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
minidns "github.com/netkits-dev/mini-dns"
|
||||
@@ -24,6 +25,12 @@ import (
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
// DelayEntry records a single delay test result.
|
||||
type DelayEntry struct {
|
||||
Time time.Time `json:"time"`
|
||||
Delay int `json:"delay"`
|
||||
}
|
||||
|
||||
type Box struct {
|
||||
createdAt time.Time
|
||||
logFactory log.Factory
|
||||
@@ -37,6 +44,39 @@ type Box struct {
|
||||
apiLn net.Listener
|
||||
clashMode string
|
||||
modeList []string
|
||||
|
||||
delayHistory map[string][]DelayEntry // outbound tag -> recent delay results
|
||||
delayHistoryMu sync.RWMutex
|
||||
}
|
||||
|
||||
const maxDelayHistory = 10
|
||||
|
||||
func (b *Box) recordDelay(tag string, delay int) {
|
||||
b.delayHistoryMu.Lock()
|
||||
defer b.delayHistoryMu.Unlock()
|
||||
if b.delayHistory == nil {
|
||||
b.delayHistory = make(map[string][]DelayEntry)
|
||||
}
|
||||
h := b.delayHistory[tag]
|
||||
h = append(h, DelayEntry{Time: time.Now(), Delay: delay})
|
||||
if len(h) > maxDelayHistory {
|
||||
h = h[len(h)-maxDelayHistory:]
|
||||
}
|
||||
b.delayHistory[tag] = h
|
||||
}
|
||||
|
||||
func (b *Box) getHistory(tag string) []map[string]any {
|
||||
b.delayHistoryMu.RLock()
|
||||
defer b.delayHistoryMu.RUnlock()
|
||||
entries := b.delayHistory[tag]
|
||||
result := make([]map[string]any, len(entries))
|
||||
for i, e := range entries {
|
||||
result[i] = map[string]any{
|
||||
"time": e.Time.Format(time.RFC3339),
|
||||
"delay": e.Delay,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func NewBox(ctx context.Context, options option.Options) (*Box, error) {
|
||||
|
||||
Reference in New Issue
Block a user