redigo连接池 - 为什么在删除过时连接时释放锁定

时间:2017-03-13 00:16:18

标签: go redis connection-pooling redigo

Redigo是redis数据库的golang客户端。它使用struct Pool来维护连接池。此结构为应用程序放置和获取并行连接保存了一个互斥锁。

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

在其get方法中,连接池首先删除陈旧(空闲超时)连接。当找到过时的连接时,池会弹出它,释放锁定,然后关闭连接,尝试再次获取锁定。

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()
        }
    }

为什么游泳池会解锁并尝试再次获取锁定,而不是在函数返回之前解锁?我想关闭一个连接可能会耗费相当多的时间,这会减慢其他goroutine等待这个互斥锁的速度。

以下是整个Pool get method

1 个答案:

答案 0 :(得分:0)

关闭连接可能会耗费相当多的时间,这会减慢其他goroutine等待此互斥锁的速度。就像@CeriseLimón所说的那样 - 这次锁定所有游泳池的使用似乎是不明智的。

解锁互斥锁后,其中一个等待的goroutines获取互斥锁。虽然get方法的goroutine仍然需要删除过时的连接,但put方法的方法可以将连接放到池中并继续尽快完成其他工作。