mirror of
https://github.com/redis/go-redis.git
synced 2025-07-28 06:42:00 +03:00
Add connnection pool and improve API.
This commit is contained in:
95
connpool.go
Normal file
95
connpool.go
Normal file
@ -0,0 +1,95 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmihailenco/bufreader"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
RW io.ReadWriter
|
||||
Rd *bufreader.Reader
|
||||
}
|
||||
|
||||
func NewConn(rw io.ReadWriter) *Conn {
|
||||
return &Conn{
|
||||
RW: rw,
|
||||
Rd: bufreader.NewSizedReader(8024),
|
||||
}
|
||||
}
|
||||
|
||||
type ConnPool struct {
|
||||
Logger *log.Logger
|
||||
cond *sync.Cond
|
||||
conns []*Conn
|
||||
OpenConn OpenConnFunc
|
||||
CloseConn CloseConnFunc
|
||||
cap, MaxCap int64
|
||||
}
|
||||
|
||||
func NewConnPool(openConn OpenConnFunc, closeConn CloseConnFunc, maxCap int64) *ConnPool {
|
||||
logger := log.New(
|
||||
os.Stdout,
|
||||
"redis.connpool: ",
|
||||
log.Ldate|log.Ltime|log.Lshortfile,
|
||||
)
|
||||
return &ConnPool{
|
||||
cond: sync.NewCond(&sync.Mutex{}),
|
||||
Logger: logger,
|
||||
conns: make([]*Conn, 0),
|
||||
OpenConn: openConn,
|
||||
CloseConn: closeConn,
|
||||
MaxCap: maxCap,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ConnPool) Get() (*Conn, bool, error) {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
|
||||
for len(p.conns) == 0 && p.cap >= p.MaxCap {
|
||||
p.cond.Wait()
|
||||
}
|
||||
|
||||
if len(p.conns) == 0 {
|
||||
rw, err := p.OpenConn()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
p.cap++
|
||||
return NewConn(rw), true, nil
|
||||
}
|
||||
|
||||
last := len(p.conns) - 1
|
||||
conn := p.conns[last]
|
||||
p.conns[last] = nil
|
||||
p.conns = p.conns[:last]
|
||||
|
||||
return conn, false, nil
|
||||
}
|
||||
|
||||
func (p *ConnPool) Add(conn *Conn) {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
p.conns = append(p.conns, conn)
|
||||
p.cond.Signal()
|
||||
}
|
||||
|
||||
func (p *ConnPool) Remove(conn *Conn) {
|
||||
p.cond.L.Lock()
|
||||
p.cap--
|
||||
p.cond.Signal()
|
||||
p.cond.L.Unlock()
|
||||
|
||||
if p.CloseConn != nil && conn != nil {
|
||||
p.CloseConn(conn.RW)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ConnPool) Len() int {
|
||||
return len(p.conns)
|
||||
}
|
Reference in New Issue
Block a user