the pool Package Import ( "errors" "IO" "Sync" "Time" ) var ( ErrInvalidConfig = errors.New ( "invalid the pool config") ErrPoolClosed = errors.New ( "the pool Closed") ) type Factory FUNC () (IO .Closer, error) of the type interface {Pool acquire () (io.Closer, error) // access to resources release (io.Closer) error // release resources Close (io.Closer) error // close the resource Shutdown () error / / pool close } of the type GenericPool struct { sync.Mutex the pool chan io.Closer maxOpen int // The maximum number of pool resources numOpen int // the number of the current resource pool minOpen int // minimum number of resource pool closed bool // pool has been closed maxLifetime time.Duration factory factory // 创建连接的方法 } func NewGenericPool(minOpen, maxOpen int, maxLifetime time.Duration, factory factory) (*GenericPool, error) { if maxOpen <= 0 || minOpen > maxOpen { return nil, ErrInvalidConfig } p := &GenericPool{ maxOpen: maxOpen, minOpen: minOpen, maxLifetime: maxLifetime, factory: factory, pool: make(chan io.Closer, maxOpen), } for i := 0; i < minOpen; i++ { closer, err := factory() if err != nil { continue } p.numOpen++ p.pool <- closer } return p, nil } func (p *GenericPool) Acquire() (io.Closer, error) { if p.closed { return nil, ErrPoolClosed } for { closer, err := p.getOrCreate() if err != nil { return nil, err } // todo maxLifttime处理 return closer, nil } } func (p *GenericPool) getOrCreate() (io.Closer, error) { select { case closer := <-p.pool: return closer, nil default: } p.Lock() if p.numOpen >= p.maxOpen { closer := <-p.pool p.Unlock() return closer, nil } // 新建连接 closer, err := p.factory() IF ERR! = Nil { p.Unlock () return nil, ERR } p.numOpen ++ p.Unlock () return Closer, nil } // release resources to the single connection pool func (p * GenericPool) Release ( closer io.Closer ) {error IF p.closed { return ErrPoolClosed } p.Lock () p.pool <- Closer p.Unlock () return nil } // Close single resource func (p * GenericPool) Close ( closer io.Closer) error { p.Lock () closer.Close () p.numOpen-- p.Unlock () return nil } // close the connection pool, releases all resources func (p * GenericPool) Shutdown ( ) error { IF p.closed { return ErrPoolClosed } p.Lock() close(p.pool) for closer := range p.pool { closer.Close() p.numOpen-- } p.closed = true p.Unlock() return nil }
golang package based channel resource pool (to encapsulate redis, mq connection pool)
Guess you like
Origin www.cnblogs.com/zipon/p/11315255.html
Recommended
Ranking