Add a conn lifetime for the pool
This commit is contained in:
		| @@ -2,6 +2,7 @@ package client | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/micro/go-micro/transport" | ||||
| ) | ||||
| @@ -15,10 +16,14 @@ type pool struct { | ||||
|  | ||||
| type poolConn struct { | ||||
| 	transport.Client | ||||
| 	created int64 | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// only hold on to this many conns | ||||
| 	maxIdleConn = 2 | ||||
| 	// only hold on to the conn for this period | ||||
| 	maxLifeTime = int64(60) | ||||
| ) | ||||
|  | ||||
| func newPool() *pool { | ||||
| @@ -34,32 +39,46 @@ func (p *poolConn) Close() error { | ||||
|  | ||||
| func (p *pool) getConn(addr string, tr transport.Transport, opts ...transport.DialOption) (*poolConn, error) { | ||||
| 	p.Lock() | ||||
| 	conns, ok := p.conns[addr] | ||||
| 	// no free conn | ||||
| 	if !ok || len(conns) == 0 { | ||||
| 		p.Unlock() | ||||
| 		// create new conn | ||||
| 		c, err := tr.Dial(addr, opts...) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 	conns := p.conns[addr] | ||||
| 	now := time.Now().Unix() | ||||
|  | ||||
| 	// while we have conns check age and then return one | ||||
| 	// otherwise we'll create a new conn | ||||
| 	for len(conns) > 0 { | ||||
| 		conn := conns[len(conns)-1] | ||||
| 		conns = conns[:len(conns)-1] | ||||
| 		p.conns[addr] = conns | ||||
|  | ||||
| 		// if conn is old kill it and move on | ||||
| 		if d := now - conn.created; d > maxLifeTime { | ||||
| 			conn.Client.Close() | ||||
| 			continue | ||||
| 		} | ||||
| 		return &poolConn{c}, nil | ||||
|  | ||||
| 		// we got a good conn, lets unlock and return it | ||||
| 		p.Unlock() | ||||
|  | ||||
| 		return conn, nil | ||||
| 	} | ||||
|  | ||||
| 	conn := conns[len(conns)-1] | ||||
| 	p.conns[addr] = conns[:len(conns)-1] | ||||
| 	p.Unlock() | ||||
| 	return conn, nil | ||||
|  | ||||
| 	// create new conn | ||||
| 	c, err := tr.Dial(addr, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &poolConn{c, time.Now().Unix()}, nil | ||||
| } | ||||
|  | ||||
| func (p *pool) release(addr string, conn *poolConn, err error) { | ||||
| 	// don't store the conn | ||||
| 	// don't store the conn if it has errored | ||||
| 	if err != nil { | ||||
| 		conn.Client.Close() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// otherwise put it back | ||||
| 	// otherwise put it back for reuse | ||||
| 	p.Lock() | ||||
| 	conns := p.conns[addr] | ||||
| 	if len(conns) >= maxIdleConn { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user