forked from mirror/redis
Use atomic.Value instead of lock for ConnPool.lastDialError
This makes the reading and writing of lastDialError from the pool faster, as atomic.Value is much more lightweight than the mutex. Note that using error in atomic.Value directly could cause panics, because errors could have inconsistent types. Thus wrap them with a simple struct.
This commit is contained in:
parent
f3d06886e6
commit
4f70db6849
|
@ -60,13 +60,16 @@ type Options struct {
|
|||
IdleCheckFrequency time.Duration
|
||||
}
|
||||
|
||||
type lastDialErrorWrap struct {
|
||||
err error
|
||||
}
|
||||
|
||||
type ConnPool struct {
|
||||
opt *Options
|
||||
|
||||
dialErrorsNum uint32 // atomic
|
||||
|
||||
lastDialErrorMu sync.RWMutex
|
||||
lastDialError error
|
||||
lastDialError atomic.Value
|
||||
|
||||
queue chan struct{}
|
||||
|
||||
|
@ -204,16 +207,15 @@ func (p *ConnPool) tryDial() {
|
|||
}
|
||||
|
||||
func (p *ConnPool) setLastDialError(err error) {
|
||||
p.lastDialErrorMu.Lock()
|
||||
p.lastDialError = err
|
||||
p.lastDialErrorMu.Unlock()
|
||||
p.lastDialError.Store(&lastDialErrorWrap{err: err})
|
||||
}
|
||||
|
||||
func (p *ConnPool) getLastDialError() error {
|
||||
p.lastDialErrorMu.RLock()
|
||||
err := p.lastDialError
|
||||
p.lastDialErrorMu.RUnlock()
|
||||
return err
|
||||
err, _ := p.lastDialError.Load().(*lastDialErrorWrap)
|
||||
if err != nil {
|
||||
return err.err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns existed connection from the pool or creates a new one.
|
||||
|
|
Loading…
Reference in New Issue