mirror of
https://github.com/redis/go-redis.git
synced 2025-12-03 18:31:14 +03:00
use min timeout to avoid waiting for too long
This commit is contained in:
29
redis.go
29
redis.go
@@ -399,10 +399,33 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
|
||||
|
||||
if finalState == pool.StateInitializing {
|
||||
// Another goroutine is initializing - WAIT for it to complete
|
||||
// Use the request context directly to respect the caller's timeout
|
||||
// This prevents goroutines from waiting longer than their request timeout
|
||||
// Use a context with timeout = min(remaining command timeout, DialTimeout)
|
||||
// This prevents waiting too long while respecting the caller's deadline
|
||||
waitCtx := ctx
|
||||
dialTimeout := c.opt.DialTimeout
|
||||
|
||||
if cmdDeadline, hasCmdDeadline := ctx.Deadline(); hasCmdDeadline {
|
||||
// Calculate remaining time until command deadline
|
||||
remainingTime := time.Until(cmdDeadline)
|
||||
// Use the minimum of remaining time and DialTimeout
|
||||
if remainingTime < dialTimeout {
|
||||
// Command deadline is sooner, use it
|
||||
waitCtx = ctx
|
||||
} else {
|
||||
// DialTimeout is shorter, cap the wait at DialTimeout
|
||||
var cancel context.CancelFunc
|
||||
waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
|
||||
defer cancel()
|
||||
}
|
||||
} else {
|
||||
// No command deadline, use DialTimeout to prevent waiting indefinitely
|
||||
var cancel context.CancelFunc
|
||||
waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
finalState, err := cn.GetStateMachine().AwaitAndTransition(
|
||||
ctx,
|
||||
waitCtx,
|
||||
[]pool.ConnState{pool.StateIdle, pool.StateInUse},
|
||||
pool.StateIdle, // Target is IDLE (but we're already there, so this is a no-op)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user