From 5fac913204209d13e9c6f6fb07b0749e5732cae9 Mon Sep 17 00:00:00 2001 From: Nedyalko Dyakov Date: Tue, 22 Apr 2025 21:00:48 +0300 Subject: [PATCH] wip, hooks refactor --- internal/internal.go | 2 -- redis.go | 29 +++++++++-------------------- sentinel.go | 1 - tx.go | 7 +++---- 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/internal/internal.go b/internal/internal.go index dbf77e26..e783d139 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -6,8 +6,6 @@ import ( "github.com/redis/go-redis/v9/internal/rand" ) -type ParentHooksMixinKey struct{} - func RetryBackoff(retry int, minBackoff, maxBackoff time.Duration) time.Duration { if retry < 0 { panic("not reached") diff --git a/redis.go b/redis.go index cbc8e60c..2fcd587f 100644 --- a/redis.go +++ b/redis.go @@ -205,6 +205,7 @@ func (hs *hooksMixin) processTxPipelineHook(ctx context.Context, cmds []Cmder) e type baseClient struct { opt *Options connPool pool.Pooler + hooksMixin onClose func() error // hook called when client is closed } @@ -352,20 +353,8 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { var err error cn.Inited = true connPool := pool.NewSingleConnPool(c.connPool, cn) - var parentHooks hooksMixin - pH := ctx.Value(internal.ParentHooksMixinKey{}) - switch pH := pH.(type) { - case nil: - parentHooks = hooksMixin{} - case hooksMixin: - parentHooks = pH.clone() - case *hooksMixin: - parentHooks = (*pH).clone() - default: - parentHooks = hooksMixin{} - } - conn := newConn(c.opt, connPool, parentHooks) + conn := newConn(c.opt, connPool, c.hooksMixin) protocol := c.opt.Protocol // By default, use RESP3 in current version. @@ -743,7 +732,6 @@ func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) type Client struct { *baseClient cmdable - hooksMixin } // NewClient returns a client to the Redis Server specified by Options. @@ -779,7 +767,7 @@ func (c *Client) WithTimeout(timeout time.Duration) *Client { } func (c *Client) Conn() *Conn { - return newConn(c.opt, pool.NewStickyConnPool(c.connPool), c.hooksMixin.clone()) + return newConn(c.opt, pool.NewStickyConnPool(c.connPool), c.hooksMixin) } // Do create a Cmd from the args and processes the cmd. @@ -790,7 +778,6 @@ func (c *Client) Do(ctx context.Context, args ...interface{}) *Cmd { } func (c *Client) Process(ctx context.Context, cmd Cmder) error { - ctx = context.WithValue(ctx, internal.ParentHooksMixinKey{}, c.hooksMixin) err := c.processHook(ctx, cmd) cmd.SetErr(err) return err @@ -913,20 +900,22 @@ type Conn struct { baseClient cmdable statefulCmdable - hooksMixin } +// newConn is a helper func to create a new Conn instance. +// the Conn instance is not thread-safe and should not be shared between goroutines. +// the parentHooks will be cloned, no need to clone before passing it. func newConn(opt *Options, connPool pool.Pooler, parentHooks hooksMixin) *Conn { c := Conn{ baseClient: baseClient{ - opt: opt, - connPool: connPool, + opt: opt, + connPool: connPool, + hooksMixin: parentHooks.clone(), }, } c.cmdable = c.Process c.statefulCmdable = c.Process - c.hooksMixin = parentHooks c.initHooks(hooks{ dial: c.baseClient.dial, process: c.baseClient.process, diff --git a/sentinel.go b/sentinel.go index 605c0d48..a708dc98 100644 --- a/sentinel.go +++ b/sentinel.go @@ -309,7 +309,6 @@ func masterReplicaDialer( // SentinelClient is a client for a Redis Sentinel. type SentinelClient struct { *baseClient - hooksMixin } func NewSentinelClient(opt *Options) *SentinelClient { diff --git a/tx.go b/tx.go index 039eaf35..0daa222e 100644 --- a/tx.go +++ b/tx.go @@ -19,16 +19,15 @@ type Tx struct { baseClient cmdable statefulCmdable - hooksMixin } func (c *Client) newTx() *Tx { tx := Tx{ baseClient: baseClient{ - opt: c.opt, - connPool: pool.NewStickyConnPool(c.connPool), + opt: c.opt, + connPool: pool.NewStickyConnPool(c.connPool), + hooksMixin: c.hooksMixin.clone(), }, - hooksMixin: c.hooksMixin.clone(), } tx.init() return &tx