update godep

This commit is contained in:
siddontang 2015-03-18 11:54:27 +08:00
parent 9f8f62b548
commit fb665e7773
2 changed files with 68 additions and 6 deletions

2
Godeps/Godeps.json generated
View File

@ -60,7 +60,7 @@
}, },
{ {
"ImportPath": "github.com/siddontang/goredis", "ImportPath": "github.com/siddontang/goredis",
"Rev": "f711beb9ecead18cf638a898610aa2c24ccb6dc7" "Rev": "ca4c5d7500bcc6850c52824caf2c49a6015c8a03"
}, },
{ {
"ImportPath": "github.com/siddontang/rdb", "ImportPath": "github.com/siddontang/rdb",

View File

@ -5,6 +5,7 @@ import (
"net" "net"
"strings" "strings"
"sync" "sync"
"time"
) )
type PoolConn struct { type PoolConn struct {
@ -30,6 +31,9 @@ type Client struct {
password string password string
conns *list.List conns *list.List
quit chan struct{}
wg sync.WaitGroup
} }
func getProto(addr string) string { func getProto(addr string) string {
@ -50,6 +54,10 @@ func NewClient(addr string, password string) *Client {
c.password = password c.password = password
c.conns = list.New() c.conns = list.New()
c.quit = make(chan struct{})
c.wg.Add(1)
go c.onCheck()
return c return c
} }
@ -105,6 +113,9 @@ func (c *Client) Close() {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
close(c.quit)
c.wg.Wait()
for c.conns.Len() > 0 { for c.conns.Len() > 0 {
e := c.conns.Front() e := c.conns.Front()
co := e.Value.(*Conn) co := e.Value.(*Conn)
@ -142,11 +153,62 @@ func (c *Client) get() (co *Conn, err error) {
func (c *Client) put(conn *Conn) { func (c *Client) put(conn *Conn) {
c.Lock() c.Lock()
if c.conns.Len() >= c.maxIdleConns { defer c.Unlock()
c.Unlock()
conn.Close() for c.conns.Len() >= c.maxIdleConns {
} else { // remove back
e := c.conns.Back()
co := e.Value.(*Conn)
c.conns.Remove(e)
co.Close()
}
c.conns.PushFront(conn) c.conns.PushFront(conn)
c.Unlock() }
func (c *Client) getIdle() *Conn {
c.Lock()
defer c.Unlock()
if c.conns.Len() == 0 {
return nil
} else {
e := c.conns.Back()
co := e.Value.(*Conn)
c.conns.Remove(e)
return co
}
}
func (c *Client) checkIdle() {
co := c.getIdle()
if co == nil {
return
}
_, err := co.Do("PING")
if err != nil {
co.Close()
} else {
c.put(co)
}
}
func (c *Client) onCheck() {
t := time.NewTicker(3 * time.Second)
defer func() {
t.Stop()
c.wg.Done()
}()
for {
select {
case <-t.C:
c.checkIdle()
case <-c.quit:
return
}
} }
} }