Fix DNS cache lock goroutine leak
The cache deduplication in Client.Exchange uses a channel-based lock per DNS question. Waiting goroutines blocked on <-cond without context awareness, causing them to accumulate indefinitely when the owning goroutine's transport call stalls. Add select on ctx.Done() so waiters respect context cancellation and timeouts.
This commit is contained in:
parent
0f3774e501
commit
e7a9c90213
1 changed files with 10 additions and 2 deletions
|
|
@ -144,7 +144,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
|||
if c.cache != nil {
|
||||
cond, loaded := c.cacheLock.LoadOrStore(question, make(chan struct{}))
|
||||
if loaded {
|
||||
<-cond
|
||||
select {
|
||||
case <-cond:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
} else {
|
||||
defer func() {
|
||||
c.cacheLock.Delete(question)
|
||||
|
|
@ -154,7 +158,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
|||
} else if c.transportCache != nil {
|
||||
cond, loaded := c.transportCacheLock.LoadOrStore(question, make(chan struct{}))
|
||||
if loaded {
|
||||
<-cond
|
||||
select {
|
||||
case <-cond:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
} else {
|
||||
defer func() {
|
||||
c.transportCacheLock.Delete(question)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue