package connection import ( "context" "time" ) type DialFunc func(context.Context) error type Reconnector struct { MaxAttempts int Delay time.Duration Dial DialFunc } func (r Reconnector) Connect(ctx context.Context) (int, error) { attempts := r.MaxAttempts if attempts <= 0 { attempts = 1 } var lastErr error for attempt := 1; attempt <= attempts; attempt++ { if err := ctx.Err(); err != nil { return attempt - 1, err } if err := r.Dial(ctx); err != nil { lastErr = err if attempt < attempts && r.Delay > 0 { select { case <-ctx.Done(): return attempt, ctx.Err() case <-time.After(r.Delay): } } continue } return attempt, nil } return attempts, lastErr }