Fix: a shared fastSingle.Do() may cause providers untouched (#2378)
This commit is contained in:
parent
c8bc11d61d
commit
19b7c7f52a
4 changed files with 16 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue