github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/app/router/strategy_leastping.go (about) 1 package router 2 3 import ( 4 "context" 5 6 "github.com/xmplusdev/xmcore/app/observatory" 7 "github.com/xmplusdev/xmcore/common" 8 "github.com/xmplusdev/xmcore/core" 9 "github.com/xmplusdev/xmcore/features/extension" 10 ) 11 12 type LeastPingStrategy struct { 13 ctx context.Context 14 observatory extension.Observatory 15 } 16 17 func (l *LeastPingStrategy) GetPrincipleTarget(strings []string) []string { 18 return []string{l.PickOutbound(strings)} 19 } 20 21 func (l *LeastPingStrategy) InjectContext(ctx context.Context) { 22 l.ctx = ctx 23 } 24 25 func (l *LeastPingStrategy) PickOutbound(strings []string) string { 26 if l.observatory == nil { 27 common.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error { 28 l.observatory = observatory 29 return nil 30 })) 31 } 32 33 observeReport, err := l.observatory.GetObservation(l.ctx) 34 if err != nil { 35 newError("cannot get observe report").Base(err).WriteToLog() 36 return "" 37 } 38 outboundsList := outboundList(strings) 39 if result, ok := observeReport.(*observatory.ObservationResult); ok { 40 status := result.Status 41 leastPing := int64(99999999) 42 selectedOutboundName := "" 43 for _, v := range status { 44 if outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing { 45 selectedOutboundName = v.OutboundTag 46 leastPing = v.Delay 47 } 48 } 49 return selectedOutboundName 50 } 51 52 // No way to understand observeReport 53 return "" 54 } 55 56 type outboundList []string 57 58 func (o outboundList) contains(name string) bool { 59 for _, v := range o { 60 if v == name { 61 return true 62 } 63 } 64 return false 65 }