go-redis icon indicating copy to clipboard operation
go-redis copied to clipboard

"dialHook" doesn't work in some case

Open hesining opened this issue 2 years ago • 2 comments

Issue tracker is used for reporting bugs and discussing new features. Please use stackoverflow for supporting issues.

Expected Behavior

"dialHook" method can work

the test code can print "aaaaa" and "bbbbb"

Current Behavior

it doesn't work when use connection pool and call "WithTimeout" before "AddHook"

the test code can only print "aaaaa"

Possible Solution

maybe we can call the "newConnPool" method again after clone the client

func NewClient(opt *Options) *Client {
	//...
	c.connPool = newConnPool(opt, c.dialHook)
	return &c
}

func (c *Client) WithTimeout(timeout time.Duration) *Client {
	clone := *c
	clone.baseClient = c.baseClient.withTimeout(timeout)
	clone.init()
	return &clone
}

Steps to Reproduce

  1. create test file and run it
package redis_test

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"net"
	"testing"
	"time"
)

func Test_Redis(t *testing.T) {
	c := redis.NewClient(&redis.Options{
		Addr:       "xxx",
		Password:   "111",
		PoolSize:   222,
		DB:         1,
		MaxRetries: -1,
	}).WithTimeout(time.Second * 5)

	clusterHook := &hook{
		dialHook: func(hook redis.DialHook) redis.DialHook {
			fmt.Println("aaaaaaa")
			return func(ctx context.Context, network, addr string) (n net.Conn, e error) {
				fmt.Println("bbbbb")
				n, e = hook(ctx, network, addr)
				return
			}
		},
	}
	c.AddHook(clusterHook)

	c.WithTimeout(time.Second * 5)

	c.Keys(context.Background(), "xx")
}

type hook struct {
	dialHook            func(hook redis.DialHook) redis.DialHook
	processHook         func(hook redis.ProcessHook) redis.ProcessHook
	processPipelineHook func(hook redis.ProcessPipelineHook) redis.ProcessPipelineHook
}

func (h *hook) DialHook(hook redis.DialHook) redis.DialHook {
	if h.dialHook != nil {
		return h.dialHook(hook)
	}
	return hook
}

func (h *hook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
	if h.processHook != nil {
		return h.processHook(hook)
	}
	return hook
}

func (h *hook) ProcessPipelineHook(hook redis.ProcessPipelineHook) redis.ProcessPipelineHook {
	if h.processPipelineHook != nil {
		return h.processPipelineHook(hook)
	}
	return hook
}


Context (Environment)

Detailed Description

Possible Implementation

hesining avatar Apr 25 '23 12:04 hesining