Search code examples
goredisconnection-poolingredigo

redigo connection pool - Why release lock when removing stale connection


Redigo is a golang client for the redis database. It uses struct Pool to maintain a pool of connections. This struct holds a mutex lock for application putting and getting connection parallelly.

type Pool struct {
    // ...
    IdleTimeout time.Duration
    mu     sync.Mutex
    // Stack of idleConn with most recently used at the front.
    idle list.List
}

In its get method, connection pool removes stale (idle timeout) connections firstly. When finding a stale connection, the pool pops it, releases lock, then closes connection, tries to acquire lock again.

func (p *Pool) get() (Conn, error) {
    p.mu.Lock()

    // Prune stale connections.

    if timeout := p.IdleTimeout; timeout > 0 {
        for i, n := 0, p.idle.Len(); i < n; i++ {
            e := p.idle.Back()
            if e == nil {
                break
            }
            ic := e.Value.(idleConn)
                if ic.t.Add(timeout).After(nowFunc()) {
                    break
                }
            p.idle.Remove(e)
            p.release()
            // Why does pool unlock and try to acquire lock again?
            p.mu.Unlock()
            // Close this stale connection.
            ic.c.Close()
            p.mu.Lock()
        }
    }

Why does pool unlock and try to acquire lock again, instead of just unlocking before function returns? I guess closing a connection may cost quite a lot time, which will slow down other goroutine waiting on this mutex.

Here is the whole Pool get method


Solution

  • Close a connection may cost quite a lot time, which will slow down other goroutine waiting on this mutex. As what @Cerise Limón said - It seems unwise to lock all use of the pool for this time.

    After unlocking the mutex, one of the waiting goroutines gets the mutex. Although goroutine for get method still needs to remove stale connections, the one for put method can put connection to pool and continue to do other work as soon as possible.