Optimization: refactor picker

This commit is contained in:
Dreamacro
2019-07-02 19:18:03 +08:00
parent 0eff8516c0
commit 7c6c147a18
9 changed files with 123 additions and 104 deletions

View File

@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"net"
"sync"
"sync/atomic"
"time"
@ -103,35 +102,22 @@ func (u *URLTest) speedTest() {
}
defer atomic.StoreInt32(&u.once, 0)
wg := sync.WaitGroup{}
wg.Add(len(u.proxies))
c := make(chan interface{})
fast := picker.SelectFast(context.Background(), c)
timer := time.NewTimer(u.interval)
ctx, cancel := context.WithTimeout(context.Background(), u.interval)
defer cancel()
picker, ctx := picker.WithContext(ctx)
for _, p := range u.proxies {
go func(p C.Proxy) {
_, err := p.URLTest(u.rawURL)
if err == nil {
c <- p
picker.Go(func() (interface{}, error) {
_, err := p.URLTest(ctx, u.rawURL)
if err != nil {
return nil, err
}
wg.Done()
}(p)
return p, nil
})
}
go func() {
wg.Wait()
close(c)
}()
select {
case <-timer.C:
// Wait for fast to return or close.
<-fast
case p, open := <-fast:
if open {
u.fast = p.(C.Proxy)
}
fast := picker.Wait()
if fast != nil {
u.fast = fast.(C.Proxy)
}
}