Chore: picker support get first error
This commit is contained in:
parent
dc9ae1edd0
commit
b033dd0369
3 changed files with 20 additions and 3 deletions
|
@ -16,7 +16,9 @@ type Picker struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
errOnce sync.Once
|
||||||
result interface{}
|
result interface{}
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPicker(ctx context.Context, cancel func()) *Picker {
|
func newPicker(ctx context.Context, cancel func()) *Picker {
|
||||||
|
@ -49,6 +51,11 @@ func (p *Picker) Wait() interface{} {
|
||||||
return p.result
|
return p.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Error return the first error (if all success return nil)
|
||||||
|
func (p *Picker) Error() error {
|
||||||
|
return p.err
|
||||||
|
}
|
||||||
|
|
||||||
// Go calls the given function in a new goroutine.
|
// Go calls the given function in a new goroutine.
|
||||||
// The first call to return a nil error cancels the group; its result will be returned by Wait.
|
// The first call to return a nil error cancels the group; its result will be returned by Wait.
|
||||||
func (p *Picker) Go(f func() (interface{}, error)) {
|
func (p *Picker) Go(f func() (interface{}, error)) {
|
||||||
|
@ -64,6 +71,10 @@ func (p *Picker) Go(f func() (interface{}, error)) {
|
||||||
p.cancel()
|
p.cancel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
p.errOnce.Do(func() {
|
||||||
|
p.err = err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,4 +36,5 @@ func TestPicker_Timeout(t *testing.T) {
|
||||||
|
|
||||||
number := picker.Wait()
|
number := picker.Wait()
|
||||||
assert.Nil(t, number)
|
assert.Nil(t, number)
|
||||||
|
assert.NotNil(t, picker.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -182,7 +183,11 @@ func (r *Resolver) batchExchange(clients []dnsClient, m *D.Msg) (msg *D.Msg, err
|
||||||
|
|
||||||
elm := fast.Wait()
|
elm := fast.Wait()
|
||||||
if elm == nil {
|
if elm == nil {
|
||||||
return nil, errors.New("All DNS requests failed")
|
err := errors.New("All DNS requests failed")
|
||||||
|
if fErr := fast.Error(); fErr != nil {
|
||||||
|
err = fmt.Errorf("%w, first error: %s", err, fErr.Error())
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = elm.(*D.Msg)
|
msg = elm.(*D.Msg)
|
||||||
|
|
Loading…
Reference in a new issue