@@ -301,6 +301,19 @@ func (c *sentinelFailover) Close() error {
301
301
return nil
302
302
}
303
303
304
+ func (c * sentinelFailover ) closeSentinel () error {
305
+ firstErr := c .pubsub .Close ()
306
+ c .pubsub = nil
307
+
308
+ err := c .sentinel .Close ()
309
+ if err != nil && firstErr == nil {
310
+ firstErr = err
311
+ }
312
+ c .sentinel = nil
313
+
314
+ return firstErr
315
+ }
316
+
304
317
func (c * sentinelFailover ) Pool () * pool.ConnPool {
305
318
c .poolOnce .Do (func () {
306
319
opt := * c .opt
@@ -331,14 +344,28 @@ func (c *sentinelFailover) MasterAddr() (string, error) {
331
344
}
332
345
333
346
func (c * sentinelFailover ) masterAddr () (string , error ) {
334
- addr := c .getMasterAddr ()
335
- if addr != "" {
336
- return addr , nil
347
+ c .mu .RLock ()
348
+ sentinel := c .sentinel
349
+ c .mu .RUnlock ()
350
+
351
+ if sentinel != nil {
352
+ addr := c .getMasterAddr (sentinel )
353
+ if addr != "" {
354
+ return addr , nil
355
+ }
337
356
}
338
357
339
358
c .mu .Lock ()
340
359
defer c .mu .Unlock ()
341
360
361
+ if c .sentinel != nil {
362
+ addr := c .getMasterAddr (c .sentinel )
363
+ if addr != "" {
364
+ return addr , nil
365
+ }
366
+ _ = c .closeSentinel ()
367
+ }
368
+
342
369
for i , sentinelAddr := range c .sentinelAddrs {
343
370
sentinel := NewSentinelClient (& Options {
344
371
Addr : sentinelAddr ,
@@ -378,27 +405,13 @@ func (c *sentinelFailover) masterAddr() (string, error) {
378
405
return "" , errors .New ("redis: all sentinels are unreachable" )
379
406
}
380
407
381
- func (c * sentinelFailover ) getMasterAddr () string {
382
- c .mu .RLock ()
383
- sentinel := c .sentinel
384
- c .mu .RUnlock ()
385
-
386
- if sentinel == nil {
387
- return ""
388
- }
389
-
408
+ func (c * sentinelFailover ) getMasterAddr (sentinel * SentinelClient ) string {
390
409
addr , err := sentinel .GetMasterAddrByName (c .masterName ).Result ()
391
410
if err != nil {
392
411
internal .Logger .Printf ("sentinel: GetMasterAddrByName name=%q failed: %s" ,
393
412
c .masterName , err )
394
- c .mu .Lock ()
395
- if c .sentinel == sentinel {
396
- _ = c .closeSentinel ()
397
- }
398
- c .mu .Unlock ()
399
413
return ""
400
414
}
401
-
402
415
return net .JoinHostPort (addr [0 ], addr [1 ])
403
416
}
404
417
@@ -413,6 +426,10 @@ func (c *sentinelFailover) switchMaster(addr string) {
413
426
c .mu .Lock ()
414
427
defer c .mu .Unlock ()
415
428
429
+ if c ._masterAddr == addr {
430
+ return
431
+ }
432
+
416
433
internal .Logger .Printf ("sentinel: new master=%q addr=%q" ,
417
434
c .masterName , addr )
418
435
_ = c .Pool ().Filter (func (cn * pool.Conn ) bool {
@@ -422,28 +439,18 @@ func (c *sentinelFailover) switchMaster(addr string) {
422
439
}
423
440
424
441
func (c * sentinelFailover ) setSentinel (sentinel * SentinelClient ) {
425
- c .discoverSentinels (sentinel )
442
+ if c .sentinel != nil {
443
+ panic ("not reached" )
444
+ }
426
445
c .sentinel = sentinel
446
+ c .discoverSentinels ()
427
447
428
448
c .pubsub = sentinel .Subscribe ("+switch-master" )
429
449
go c .listen (c .pubsub )
430
450
}
431
451
432
- func (c * sentinelFailover ) closeSentinel () error {
433
- firstErr := c .pubsub .Close ()
434
- c .pubsub = nil
435
-
436
- err := c .sentinel .Close ()
437
- if err != nil && firstErr == nil {
438
- firstErr = err
439
- }
440
- c .sentinel = nil
441
-
442
- return firstErr
443
- }
444
-
445
- func (c * sentinelFailover ) discoverSentinels (sentinel * SentinelClient ) {
446
- sentinels , err := sentinel .Sentinels (c .masterName ).Result ()
452
+ func (c * sentinelFailover ) discoverSentinels () {
453
+ sentinels , err := c .sentinel .Sentinels (c .masterName ).Result ()
447
454
if err != nil {
448
455
internal .Logger .Printf ("sentinel: Sentinels master=%q failed: %s" , c .masterName , err )
449
456
return
0 commit comments