From 2f3f017aa45b6be9766e5ab150033474b507ece7 Mon Sep 17 00:00:00 2001 From: newacorn Date: Tue, 13 Aug 2024 06:17:33 +0800 Subject: [PATCH] TestHostClientMaxConnWaitTimeoutError test case sometimes fails The current implementation makes some incorrect assumptions about observing changes in the state of wantConn. --- client.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 42a01d5dbb..11b3e16b8d 100644 --- a/client.go +++ b/client.go @@ -1552,6 +1552,7 @@ func (c *HostClient) acquireConn(reqTimeout time.Duration, connectionClose bool) case <-w.ready: return w.conn, w.err case <-tc.C: + c.connsWait.failedWaiters.Add(1) if timeoutOverridden { return nil, ErrTimeout } @@ -1697,6 +1698,7 @@ func (c *HostClient) decConnsCount() { dialed = true break } + c.connsWait.failedWaiters.Add(-1) } } if !dialed { @@ -1751,6 +1753,7 @@ func (c *HostClient) releaseConn(cc *clientConn) { delivered = w.tryDeliver(cc, nil) break } + c.connsWait.failedWaiters.Add(-1) } } if !delivered { @@ -2106,11 +2109,17 @@ type wantConnQueue struct { head []*wantConn tail []*wantConn headPos int + // failedWaiters is the number of waiters in the head or tail queue, + // but is invalid. + // These state waiters cannot truly be considered as waiters; the current + // implementation does not immediately remove them when they become + // invalid but instead only marks them. + failedWaiters atomic.Int64 } // len returns the number of items in the queue. func (q *wantConnQueue) len() int { - return len(q.head) - q.headPos + len(q.tail) + return len(q.head) - q.headPos + len(q.tail) - int(q.failedWaiters.Load()) } // pushBack adds w to the back of the queue. @@ -2154,6 +2163,7 @@ func (q *wantConnQueue) clearFront() (cleaned bool) { return cleaned } q.popFront() + q.failedWaiters.Add(-1) cleaned = true } }