fix: auto retry in exchangeWithoutCache
This commit is contained in:
parent
16f8f77f5d
commit
23f286f24e
1 changed files with 21 additions and 4 deletions
|
@ -187,12 +187,16 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
|
||||||
func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
||||||
q := m.Question[0]
|
q := m.Question[0]
|
||||||
|
|
||||||
ch := r.group.DoChan(q.String(), func() (result any, err error) {
|
retryNum := 0
|
||||||
|
retryMax := 3
|
||||||
|
fn := func() (result any, err error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout) // reset timeout in singleflight
|
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout) // reset timeout in singleflight
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
result = retryNum
|
||||||
|
retryNum++
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +214,9 @@ func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.M
|
||||||
return r.batchExchange(ctx, matched, m)
|
return r.batchExchange(ctx, matched, m)
|
||||||
}
|
}
|
||||||
return r.batchExchange(ctx, r.main, m)
|
return r.batchExchange(ctx, r.main, m)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
ch := r.group.DoChan(q.String(), fn)
|
||||||
|
|
||||||
var result singleflight.Result
|
var result singleflight.Result
|
||||||
|
|
||||||
|
@ -219,13 +225,24 @@ func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.M
|
||||||
break
|
break
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
select {
|
select {
|
||||||
case result = <-ch:
|
case result = <-ch: // maybe ctxDone and chFinish in same time, get DoChan's result as much as possible
|
||||||
break
|
break
|
||||||
|
default:
|
||||||
|
go func() { // start a retrying monitor in background
|
||||||
|
result := <-ch
|
||||||
|
ret, err, shared := result.Val, result.Err, result.Shared
|
||||||
|
if err != nil && !shared && ret.(int) < retryMax { // retry
|
||||||
|
r.group.DoChan(q.String(), fn)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
return nil, ctx.Err()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err, shared := result.Val, result.Err, result.Shared
|
ret, err, shared := result.Val, result.Err, result.Shared
|
||||||
|
if err != nil && !shared && ret.(int) < retryMax { // retry
|
||||||
|
r.group.DoChan(q.String(), fn)
|
||||||
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
msg = ret.(*D.Msg)
|
msg = ret.(*D.Msg)
|
||||||
|
|
Loading…
Reference in a new issue