Skip to content

Commit e47f040

Browse files
ndyakovcyningsun
authored andcommitted
use min timeout to avoid waiting for too long
1 parent 547bfb8 commit e47f040

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

redis.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,33 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
399399

400400
if finalState == pool.StateInitializing {
401401
// Another goroutine is initializing - WAIT for it to complete
402-
// Use the request context directly to respect the caller's timeout
403-
// This prevents goroutines from waiting longer than their request timeout
402+
// Use a context with timeout = min(remaining command timeout, DialTimeout)
403+
// This prevents waiting too long while respecting the caller's deadline
404+
waitCtx := ctx
405+
dialTimeout := c.opt.DialTimeout
406+
407+
if cmdDeadline, hasCmdDeadline := ctx.Deadline(); hasCmdDeadline {
408+
// Calculate remaining time until command deadline
409+
remainingTime := time.Until(cmdDeadline)
410+
// Use the minimum of remaining time and DialTimeout
411+
if remainingTime < dialTimeout {
412+
// Command deadline is sooner, use it
413+
waitCtx = ctx
414+
} else {
415+
// DialTimeout is shorter, cap the wait at DialTimeout
416+
var cancel context.CancelFunc
417+
waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
418+
defer cancel()
419+
}
420+
} else {
421+
// No command deadline, use DialTimeout to prevent waiting indefinitely
422+
var cancel context.CancelFunc
423+
waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
424+
defer cancel()
425+
}
426+
404427
finalState, err := cn.GetStateMachine().AwaitAndTransition(
405-
ctx,
428+
waitCtx,
406429
[]pool.ConnState{pool.StateIdle, pool.StateInUse},
407430
pool.StateIdle, // Target is IDLE (but we're already there, so this is a no-op)
408431
)

0 commit comments

Comments
 (0)