From 19b7c7f52afc4d43fa87a8dc9bbdb7ca340c2646 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Fri, 4 Nov 2022 13:11:01 +0800 Subject: [PATCH] Fix: a shared fastSingle.Do() may cause providers untouched (#2378) --- adapter/outboundgroup/common.go | 11 ++++++++--- adapter/outboundgroup/urltest.go | 5 ++++- adapter/provider/provider.go | 6 ++---- constant/provider/interface.go | 4 ++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/adapter/outboundgroup/common.go b/adapter/outboundgroup/common.go index 758c780..b1f0570 100644 --- a/adapter/outboundgroup/common.go +++ b/adapter/outboundgroup/common.go @@ -11,14 +11,19 @@ const ( defaultGetProxiesDuration = time.Second * 5 ) +func touchProviders(providers []provider.ProxyProvider) { + for _, provider := range providers { + provider.Touch() + } +} + func getProvidersProxies(providers []provider.ProxyProvider, touch bool) []C.Proxy { proxies := []C.Proxy{} for _, provider := range providers { if touch { - proxies = append(proxies, provider.ProxiesWithTouch()...) - } else { - proxies = append(proxies, provider.Proxies()...) + provider.Touch() } + proxies = append(proxies, provider.Proxies()...) } return proxies } diff --git a/adapter/outboundgroup/urltest.go b/adapter/outboundgroup/urltest.go index fd6d681..79234ec 100644 --- a/adapter/outboundgroup/urltest.go +++ b/adapter/outboundgroup/urltest.go @@ -66,7 +66,7 @@ func (u *URLTest) proxies(touch bool) []C.Proxy { } func (u *URLTest) fast(touch bool) C.Proxy { - elm, _, _ := u.fastSingle.Do(func() (any, error) { + elm, _, shared := u.fastSingle.Do(func() (any, error) { proxies := u.proxies(touch) fast := proxies[0] min := fast.LastDelay() @@ -95,6 +95,9 @@ func (u *URLTest) fast(touch bool) C.Proxy { return u.fastNode, nil }) + if shared && touch { // a shared fastSingle.Do() may cause providers untouched, so we touch them again + touchProviders(u.providers) + } return elm.(C.Proxy) } diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index 442b4b4..80611ac 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -78,9 +78,8 @@ func (pp *proxySetProvider) Proxies() []C.Proxy { return pp.proxies } -func (pp *proxySetProvider) ProxiesWithTouch() []C.Proxy { +func (pp *proxySetProvider) Touch() { pp.healthCheck.touch() - return pp.Proxies() } func (pp *proxySetProvider) setProxies(proxies []C.Proxy) { @@ -205,9 +204,8 @@ func (cp *compatibleProvider) Proxies() []C.Proxy { return cp.proxies } -func (cp *compatibleProvider) ProxiesWithTouch() []C.Proxy { +func (cp *compatibleProvider) Touch() { cp.healthCheck.touch() - return cp.Proxies() } func stopCompatibleProvider(pd *CompatibleProvider) { diff --git a/constant/provider/interface.go b/constant/provider/interface.go index 53bda7e..1864f36 100644 --- a/constant/provider/interface.go +++ b/constant/provider/interface.go @@ -66,9 +66,9 @@ type Provider interface { type ProxyProvider interface { Provider Proxies() []constant.Proxy - // ProxiesWithTouch is used to inform the provider that the proxy is actually being used while getting the list of proxies. + // Touch is used to inform the provider that the proxy is actually being used while getting the list of proxies. // Commonly used in DialContext and DialPacketConn - ProxiesWithTouch() []constant.Proxy + Touch() HealthCheck() }