Skip to content

Commit 24fa725

Browse files
committed
feat: add lock for hooks.dial
Signed-off-by: monkey92t <golang@88.com>
1 parent e309eaf commit 24fa725

File tree

5 files changed

+35
-11
lines changed

5 files changed

+35
-11
lines changed

cluster.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ type ClusterClient struct {
838838
state *clusterStateHolder
839839
cmdsInfoCache *cmdsInfoCache
840840
cmdable
841-
hooksMixin
841+
*hooksMixin
842842
}
843843

844844
// NewClusterClient returns a Redis Cluster client as described in
@@ -847,8 +847,9 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
847847
opt.init()
848848

849849
c := &ClusterClient{
850-
opt: opt,
851-
nodes: newClusterNodes(opt),
850+
opt: opt,
851+
nodes: newClusterNodes(opt),
852+
hooksMixin: &hooksMixin{},
852853
}
853854

854855
c.state = newClusterStateHolder(c.loadState)

redis.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"net"
88
"strings"
9+
"sync"
910
"sync/atomic"
1011
"time"
1112

@@ -44,6 +45,8 @@ type hooksMixin struct {
4445
slice []Hook
4546
initial hooks
4647
current hooks
48+
49+
hooksMu sync.RWMutex
4750
}
4851

4952
func (hs *hooksMixin) initHooks(hooks hooks) {
@@ -117,6 +120,9 @@ func (hs *hooksMixin) AddHook(hook Hook) {
117120
func (hs *hooksMixin) chain() {
118121
hs.initial.setDefaults()
119122

123+
hs.hooksMu.Lock()
124+
defer hs.hooksMu.Unlock()
125+
120126
hs.current.dial = hs.initial.dial
121127
hs.current.process = hs.initial.process
122128
hs.current.pipeline = hs.initial.pipeline
@@ -138,8 +144,15 @@ func (hs *hooksMixin) chain() {
138144
}
139145
}
140146

141-
func (hs *hooksMixin) clone() hooksMixin {
142-
clone := *hs
147+
func (hs *hooksMixin) clone() *hooksMixin {
148+
hs.hooksMu.Lock()
149+
defer hs.hooksMu.Unlock()
150+
151+
clone := &hooksMixin{
152+
slice: hs.slice,
153+
initial: hs.initial,
154+
current: hs.current,
155+
}
143156
l := len(clone.slice)
144157
clone.slice = clone.slice[:l:l]
145158
return clone
@@ -166,7 +179,11 @@ func (hs *hooksMixin) withProcessPipelineHook(
166179
}
167180

168181
func (hs *hooksMixin) dialHook(ctx context.Context, network, addr string) (net.Conn, error) {
169-
return hs.current.dial(ctx, network, addr)
182+
hs.hooksMu.RLock()
183+
conn, err := hs.current.dial(ctx, network, addr)
184+
hs.hooksMu.RUnlock()
185+
186+
return conn, err
170187
}
171188

172189
func (hs *hooksMixin) processHook(ctx context.Context, cmd Cmder) error {
@@ -588,8 +605,8 @@ func (c *baseClient) context(ctx context.Context) context.Context {
588605
// of idle connections. You can control the pool size with Config.PoolSize option.
589606
type Client struct {
590607
*baseClient
608+
*hooksMixin
591609
cmdable
592-
hooksMixin
593610
}
594611

595612
// NewClient returns a client to the Redis Server specified by Options.
@@ -600,6 +617,7 @@ func NewClient(opt *Options) *Client {
600617
baseClient: &baseClient{
601618
opt: opt,
602619
},
620+
hooksMixin: &hooksMixin{},
603621
}
604622
c.init()
605623
c.connPool = newConnPool(opt, c.dialHook)
@@ -620,6 +638,7 @@ func (c *Client) init() {
620638
func (c *Client) WithTimeout(timeout time.Duration) *Client {
621639
clone := *c
622640
clone.baseClient = c.baseClient.withTimeout(timeout)
641+
clone.hooksMixin = c.hooksMixin.clone()
623642
clone.init()
624643
return &clone
625644
}
@@ -758,7 +777,7 @@ type Conn struct {
758777
baseClient
759778
cmdable
760779
statefulCmdable
761-
hooksMixin
780+
*hooksMixin
762781
}
763782

764783
func newConn(opt *Options, connPool pool.Pooler) *Conn {
@@ -767,6 +786,7 @@ func newConn(opt *Options, connPool pool.Pooler) *Conn {
767786
opt: opt,
768787
connPool: connPool,
769788
},
789+
hooksMixin: &hooksMixin{},
770790
}
771791

772792
c.cmdable = c.Process

ring.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ func (c *ringSharding) Close() error {
487487
// Otherwise you should use Redis Cluster.
488488
type Ring struct {
489489
cmdable
490-
hooksMixin
490+
*hooksMixin
491491

492492
opt *RingOptions
493493
sharding *ringSharding
@@ -504,6 +504,7 @@ func NewRing(opt *RingOptions) *Ring {
504504
opt: opt,
505505
sharding: newRingSharding(opt),
506506
heartbeatCancelFn: hbCancel,
507+
hooksMixin: &hooksMixin{},
507508
}
508509

509510
ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo)

sentinel.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
211211
baseClient: &baseClient{
212212
opt: opt,
213213
},
214+
hooksMixin: &hooksMixin{},
214215
}
215216
rdb.init()
216217

@@ -267,7 +268,7 @@ func masterReplicaDialer(
267268
// SentinelClient is a client for a Redis Sentinel.
268269
type SentinelClient struct {
269270
*baseClient
270-
hooksMixin
271+
*hooksMixin
271272
}
272273

273274
func NewSentinelClient(opt *Options) *SentinelClient {
@@ -276,6 +277,7 @@ func NewSentinelClient(opt *Options) *SentinelClient {
276277
baseClient: &baseClient{
277278
opt: opt,
278279
},
280+
hooksMixin: &hooksMixin{},
279281
}
280282

281283
c.initHooks(hooks{

tx.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type Tx struct {
1919
baseClient
2020
cmdable
2121
statefulCmdable
22-
hooksMixin
22+
*hooksMixin
2323
}
2424

2525
func (c *Client) newTx() *Tx {

0 commit comments

Comments
 (0)