MCPcopy
hub / github.com/redis/go-redis / initConn

Method initConn

redis.go:483–796  ·  view source on GitHub ↗
(ctx context.Context, cn *pool.Conn)

Source from the content-addressed store, hash-verified

481}
482
483func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
484 // This function is called in two scenarios:
485 // 1. First-time init: Connection is in CREATED state (from pool.Get())
486 // - We need to transition CREATED → INITIALIZING and do the initialization
487 // - If another goroutine is already initializing, we WAIT for it to finish
488 // 2. Re-initialization: Connection is in INITIALIZING state (from SetNetConnAndInitConn())
489 // - We're already in INITIALIZING, so just proceed with initialization
490
491 currentState := cn.GetStateMachine().GetState()
492
493 // Fast path: Check if already initialized (IDLE or IN_USE)
494 if currentState == pool.StateIdle || currentState == pool.StateInUse {
495 return nil
496 }
497
498 // If in CREATED state, try to transition to INITIALIZING
499 if currentState == pool.StateCreated {
500 finalState, err := cn.GetStateMachine().TryTransition([]pool.ConnState{pool.StateCreated}, pool.StateInitializing)
501 if err != nil {
502 // Another goroutine is initializing or connection is in unexpected state
503 // Check what state we're in now
504 if finalState == pool.StateIdle || finalState == pool.StateInUse {
505 // Already initialized by another goroutine
506 return nil
507 }
508
509 if finalState == pool.StateInitializing {
510 // Another goroutine is initializing - WAIT for it to complete
511 // Use a context with timeout = min(remaining command timeout, DialTimeout)
512 // This prevents waiting too long while respecting the caller's deadline
513 var waitCtx context.Context
514 var cancel context.CancelFunc
515 dialTimeout := c.opt.DialTimeout
516
517 if cmdDeadline, hasCmdDeadline := ctx.Deadline(); hasCmdDeadline {
518 // Calculate remaining time until command deadline
519 remainingTime := time.Until(cmdDeadline)
520 // Use the minimum of remaining time and DialTimeout
521 if remainingTime < dialTimeout {
522 // Command deadline is sooner, use it
523 waitCtx = ctx
524 } else {
525 // DialTimeout is shorter, cap the wait at DialTimeout
526 waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
527 }
528 } else {
529 // No command deadline, use DialTimeout to prevent waiting indefinitely
530 waitCtx, cancel = context.WithTimeout(ctx, dialTimeout)
531 }
532 if cancel != nil {
533 defer cancel()
534 }
535
536 finalState, err := cn.GetStateMachine().AwaitAndTransition(
537 waitCtx,
538 []pool.ConnState{pool.StateIdle, pool.StateInUse},
539 pool.StateIdle, // Target is IDLE (but we're already there, so this is a no-op)
540 )

Callers 7

_getConnMethod · 0.95
createInitConnFuncMethod · 0.95
pubSubMethod · 0.80
pubSubMethod · 0.80
initConnOnMockServerFunction · 0.80
pubSubMethod · 0.80

Calls 15

reAuthConnectionMethod · 0.95
onAuthenticationErrMethod · 0.95
StringMethod · 0.95
createInitConnFuncMethod · 0.95
NewSingleConnPoolFunction · 0.92
GetMetricErrorCallbackFunction · 0.92
newConnFunction · 0.85
isRedisErrorFunction · 0.85
VersionFunction · 0.85
WithLibraryNameFunction · 0.85
WithLibraryVersionFunction · 0.85

Tested by 2

initConnOnMockServerFunction · 0.64