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
|
defaultGetProxiesDuration = time.Second * 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func touchProviders(providers []provider.ProxyProvider) {
|
||||||
|
for _, provider := range providers {
|
||||||
|
provider.Touch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getProvidersProxies(providers []provider.ProxyProvider, touch bool) []C.Proxy {
|
func getProvidersProxies(providers []provider.ProxyProvider, touch bool) []C.Proxy {
|
||||||
proxies := []C.Proxy{}
|
proxies := []C.Proxy{}
|
||||||
for _, provider := range providers {
|
for _, provider := range providers {
|
||||||
if touch {
|
if touch {
|
||||||
proxies = append(proxies, provider.ProxiesWithTouch()...)
|
provider.Touch()
|
||||||
} else {
|
|
||||||
proxies = append(proxies, provider.Proxies()...)
|
|
||||||
}
|
}
|
||||||
|
proxies = append(proxies, provider.Proxies()...)
|
||||||
}
|
}
|
||||||
return proxies
|
return proxies
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (u *URLTest) proxies(touch bool) []C.Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *URLTest) fast(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)
|
proxies := u.proxies(touch)
|
||||||
fast := proxies[0]
|
fast := proxies[0]
|
||||||
min := fast.LastDelay()
|
min := fast.LastDelay()
|
||||||
|
@ -95,6 +95,9 @@ func (u *URLTest) fast(touch bool) C.Proxy {
|
||||||
|
|
||||||
return u.fastNode, nil
|
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)
|
return elm.(C.Proxy)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,8 @@ func (pp *proxySetProvider) Proxies() []C.Proxy {
|
||||||
return pp.proxies
|
return pp.proxies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *proxySetProvider) ProxiesWithTouch() []C.Proxy {
|
func (pp *proxySetProvider) Touch() {
|
||||||
pp.healthCheck.touch()
|
pp.healthCheck.touch()
|
||||||
return pp.Proxies()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *proxySetProvider) setProxies(proxies []C.Proxy) {
|
func (pp *proxySetProvider) setProxies(proxies []C.Proxy) {
|
||||||
|
@ -205,9 +204,8 @@ func (cp *compatibleProvider) Proxies() []C.Proxy {
|
||||||
return cp.proxies
|
return cp.proxies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *compatibleProvider) ProxiesWithTouch() []C.Proxy {
|
func (cp *compatibleProvider) Touch() {
|
||||||
cp.healthCheck.touch()
|
cp.healthCheck.touch()
|
||||||
return cp.Proxies()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopCompatibleProvider(pd *CompatibleProvider) {
|
func stopCompatibleProvider(pd *CompatibleProvider) {
|
||||||
|
|
|
@ -66,9 +66,9 @@ type Provider interface {
|
||||||
type ProxyProvider interface {
|
type ProxyProvider interface {
|
||||||
Provider
|
Provider
|
||||||
Proxies() []constant.Proxy
|
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
|
// Commonly used in DialContext and DialPacketConn
|
||||||
ProxiesWithTouch() []constant.Proxy
|
Touch()
|
||||||
HealthCheck()
|
HealthCheck()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue