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:
Yuxuan 'fishy' Wang 2020-07-13 15:38:11 -07:00
parent f3d06886e6
commit 4f70db6849
1 changed files with 11 additions and 9 deletions

View File

@ -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.