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() }