Chore: picker support get first error
This commit is contained in:
parent
dc9ae1edd0
commit
b033dd0369
3 changed files with 20 additions and 3 deletions
|
@ -15,8 +15,10 @@ type Picker struct {
|
|||
|
||||
wg sync.WaitGroup
|
||||
|
||||
once sync.Once
|
||||
result interface{}
|
||||
once sync.Once
|
||||
errOnce sync.Once
|
||||
result interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
func newPicker(ctx context.Context, cancel func()) *Picker {
|
||||
|
@ -49,6 +51,11 @@ func (p *Picker) Wait() interface{} {
|
|||
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.
|
||||
// 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)) {
|
||||
|
@ -64,6 +71,10 @@ func (p *Picker) Go(f func() (interface{}, error)) {
|
|||
p.cancel()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
p.errOnce.Do(func() {
|
||||
p.err = err
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -36,4 +36,5 @@ func TestPicker_Timeout(t *testing.T) {
|
|||
|
||||
number := picker.Wait()
|
||||
assert.Nil(t, number)
|
||||
assert.NotNil(t, picker.Error())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strings"
|
||||
|
@ -182,7 +183,11 @@ func (r *Resolver) batchExchange(clients []dnsClient, m *D.Msg) (msg *D.Msg, err
|
|||
|
||||
elm := fast.Wait()
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue