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

@ -1,6 +1,7 @@
package adapters
import (
"context"
"encoding/json"
"errors"
"net"
@ -99,7 +100,7 @@ func (p *Proxy) MarshalJSON() ([]byte, error) {
}
// URLTest get the delay for the specified URL
func (p *Proxy) URLTest(url string) (t uint16, err error) {
func (p *Proxy) URLTest(ctx context.Context, url string) (t uint16, err error) {
defer func() {
p.alive = err == nil
record := C.DelayHistory{Time: time.Now()}
@ -123,6 +124,13 @@ func (p *Proxy) URLTest(url string) (t uint16, err error) {
return
}
defer instance.Close()
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return
}
req = req.WithContext(ctx)
transport := &http.Transport{
Dial: func(string, string) (net.Conn, error) {
return instance, nil
@ -133,8 +141,9 @@ func (p *Proxy) URLTest(url string) (t uint16, err error) {
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
client := http.Client{Transport: transport}
resp, err := client.Get(url)
resp, err := client.Do(req)
if err != nil {
return
}

View File

@ -1,6 +1,7 @@
package adapters
import (
"context"
"encoding/json"
"errors"
"net"
@ -90,7 +91,7 @@ func (f *Fallback) validTest() {
for _, p := range f.proxies {
go func(p C.Proxy) {
p.URLTest(f.rawURL)
p.URLTest(context.Background(), f.rawURL)
wg.Done()
}(p)
}

View File

@ -1,6 +1,7 @@
package adapters
import (
"context"
"encoding/json"
"errors"
"net"
@ -95,7 +96,7 @@ func (lb *LoadBalance) validTest() {
for _, p := range lb.proxies {
go func(p C.Proxy) {
p.URLTest(lb.rawURL)
p.URLTest(context.Background(), lb.rawURL)
wg.Done()
}(p)
}

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