Fix: use the fastest whether the result is successful

This commit is contained in:
Dreamacro
2020-02-14 16:36:20 +08:00
parent 6641bf7c07
commit 8b5e511426
5 changed files with 30 additions and 63 deletions

View File

@ -17,15 +17,12 @@ type Picker struct {
once sync.Once
result interface{}
firstDone chan struct{}
}
func newPicker(ctx context.Context, cancel func()) *Picker {
return &Picker{
ctx: ctx,
cancel: cancel,
firstDone: make(chan struct{}, 1),
ctx: ctx,
cancel: cancel,
}
}
@ -42,12 +39,6 @@ func WithTimeout(ctx context.Context, timeout time.Duration) (*Picker, context.C
return newPicker(ctx, cancel), ctx
}
// WithoutAutoCancel returns a new Picker and an associated Context derived from ctx,
// but it wouldn't cancel context when the first element return.
func WithoutAutoCancel(ctx context.Context) *Picker {
return newPicker(ctx, nil)
}
// Wait blocks until all function calls from the Go method have returned,
// then returns the first nil error result (if any) from them.
func (p *Picker) Wait() interface{} {
@ -58,17 +49,6 @@ func (p *Picker) Wait() interface{} {
return p.result
}
// WaitWithoutCancel blocks until the first result return, if timeout will return nil.
// The return of this function will not wait for the cancel of context.
func (p *Picker) WaitWithoutCancel() interface{} {
select {
case <-p.firstDone:
return p.result
case <-p.ctx.Done():
return p.result
}
}
// 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)) {
@ -80,7 +60,6 @@ func (p *Picker) Go(f func() (interface{}, error)) {
if ret, err := f(); err == nil {
p.once.Do(func() {
p.result = ret
p.firstDone <- struct{}{}
if p.cancel != nil {
p.cancel()
}