1
0
mirror of https://github.com/redis/go-redis.git synced 2025-07-25 08:21:55 +03:00

Extract pipeline and multi/exec support to separate files.

This commit is contained in:
Vladimir Mihailenco
2012-08-11 17:42:10 +03:00
parent 83664bb3a8
commit 2f4156dd04
8 changed files with 1273 additions and 1021 deletions

View File

@ -9,11 +9,11 @@ import (
)
type Conn struct {
RW io.ReadWriter
RW io.ReadWriteCloser
Rd *bufio.Reader
}
func NewConn(rw io.ReadWriter) *Conn {
func NewConn(rw io.ReadWriteCloser) *Conn {
return &Conn{
RW: rw,
Rd: bufio.NewReaderSize(rw, 1024),
@ -22,10 +22,10 @@ func NewConn(rw io.ReadWriter) *Conn {
type ConnPool interface {
Get() (*Conn, bool, error)
Add(*Conn)
Remove(*Conn)
Add(*Conn) error
Remove(*Conn) error
Len() int
Close()
Close() error
}
//------------------------------------------------------------------------------
@ -36,10 +36,10 @@ type MultiConnPool struct {
conns []*Conn
OpenConn OpenConnFunc
CloseConn CloseConnFunc
cap, MaxCap int64
cap, MaxCap int
}
func NewMultiConnPool(openConn OpenConnFunc, closeConn CloseConnFunc, maxCap int64) *MultiConnPool {
func NewMultiConnPool(openConn OpenConnFunc, closeConn CloseConnFunc, maxCap int) *MultiConnPool {
logger := log.New(
os.Stdout,
"redis.connpool: ",
@ -81,47 +81,74 @@ func (p *MultiConnPool) Get() (*Conn, bool, error) {
return conn, false, nil
}
func (p *MultiConnPool) Add(conn *Conn) {
func (p *MultiConnPool) Add(conn *Conn) error {
p.cond.L.Lock()
defer p.cond.L.Unlock()
p.conns = append(p.conns, conn)
p.cond.Signal()
return nil
}
func (p *MultiConnPool) 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 *MultiConnPool) Remove(conn *Conn) error {
defer func() {
p.cond.L.Lock()
p.cap--
p.cond.Signal()
p.cond.L.Unlock()
}()
if conn == nil {
return nil
}
return p.closeConn(conn)
}
func (p *MultiConnPool) Len() int {
return len(p.conns)
}
func (p *MultiConnPool) Close() {}
func (p *MultiConnPool) Close() error {
p.cond.L.Lock()
defer p.cond.L.Unlock()
for _, conn := range p.conns {
err := p.closeConn(conn)
if err != nil {
return err
}
}
p.conns = make([]*Conn, 0)
p.cap = 0
return nil
}
func (p *MultiConnPool) closeConn(conn *Conn) error {
if p.CloseConn != nil {
err := p.CloseConn(conn.RW)
if err != nil {
return err
}
}
return conn.RW.Close()
}
//------------------------------------------------------------------------------
type SingleConnPool struct {
mtx sync.Mutex
pool ConnPool
conn *Conn
mtx sync.Mutex
pool ConnPool
conn *Conn
isReusable bool
}
func NewSingleConnPoolConn(pool ConnPool, conn *Conn) *SingleConnPool {
func NewSingleConnPoolConn(pool ConnPool, conn *Conn, isReusable bool) *SingleConnPool {
return &SingleConnPool{
pool: pool,
conn: conn,
pool: pool,
conn: conn,
isReusable: isReusable,
}
}
func NewSingleConnPool(pool ConnPool) *SingleConnPool {
return NewSingleConnPoolConn(pool, nil)
func NewSingleConnPool(pool ConnPool, isReusable bool) *SingleConnPool {
return NewSingleConnPoolConn(pool, nil, isReusable)
}
func (p *SingleConnPool) Get() (*Conn, bool, error) {
@ -138,17 +165,32 @@ func (p *SingleConnPool) Get() (*Conn, bool, error) {
return p.conn, isNew, nil
}
func (p *SingleConnPool) Add(conn *Conn) {}
func (p *SingleConnPool) Add(conn *Conn) error {
return nil
}
func (p *SingleConnPool) Remove(conn *Conn) {}
func (p *SingleConnPool) Remove(conn *Conn) error {
return nil
}
func (p *SingleConnPool) Len() int {
return 1
}
func (p *SingleConnPool) Close() {
func (p *SingleConnPool) Close() error {
p.mtx.Lock()
defer p.mtx.Unlock()
p.pool.Add(p.conn)
if p.conn == nil {
return nil
}
var err error
if p.isReusable {
err = p.pool.Add(p.conn)
} else {
err = p.pool.Remove(p.conn)
}
p.conn = nil
return err
}