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