vitess-gh/go/vt/tabletserver/conn_pool.go

167 строки
3.6 KiB
Go
Исходник Обычный вид История

// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
2012-02-25 11:30:03 +04:00
package tabletserver
import (
"sync"
2012-02-25 11:30:03 +04:00
"time"
2013-04-11 02:43:10 +04:00
"github.com/youtube/vitess/go/pools"
"github.com/youtube/vitess/go/stats"
2012-02-25 11:30:03 +04:00
)
// ConnectionPool re-exposes ResourcePool as a pool of DBConnection objects
2012-02-25 11:30:03 +04:00
type ConnectionPool struct {
pool *pools.ResourcePool
mu sync.Mutex
capacity int
idleTimeout time.Duration
2012-02-25 11:30:03 +04:00
}
func NewConnectionPool(name string, capacity int, idleTimeout time.Duration) *ConnectionPool {
cp := &ConnectionPool{capacity: capacity, idleTimeout: idleTimeout}
if name == "" {
return cp
}
stats.Publish(name+"Capacity", stats.IntFunc(cp.Capacity))
stats.Publish(name+"Available", stats.IntFunc(cp.Available))
stats.Publish(name+"MaxCap", stats.IntFunc(cp.MaxCap))
stats.Publish(name+"WaitCount", stats.IntFunc(cp.WaitCount))
stats.Publish(name+"WaitTime", stats.DurationFunc(cp.WaitTime))
stats.Publish(name+"IdleTimeout", stats.DurationFunc(cp.IdleTimeout))
return cp
2012-02-25 11:30:03 +04:00
}
2013-04-11 02:43:10 +04:00
func (cp *ConnectionPool) Open(connFactory CreateConnectionFunc) {
f := func() (pools.Resource, error) {
c, err := connFactory()
if err != nil {
return nil, err
}
2013-04-11 02:43:10 +04:00
return &pooledConnection{c, cp}, nil
2012-02-25 11:30:03 +04:00
}
cp.pool = pools.NewResourcePool(f, cp.capacity, cp.capacity, cp.idleTimeout)
}
func (cp *ConnectionPool) Close() {
cp.pool.Close()
cp.pool = nil
2012-02-25 11:30:03 +04:00
}
// You must call Recycle on the PoolConnection once done.
2013-04-11 02:43:10 +04:00
func (cp *ConnectionPool) Get() PoolConnection {
r, err := cp.pool.Get()
if err != nil {
panic(NewTabletErrorSql(FATAL, err))
2012-02-25 11:30:03 +04:00
}
return r.(*pooledConnection)
2012-02-25 11:30:03 +04:00
}
// You must call Recycle on the PoolConnection once done.
2013-04-11 02:43:10 +04:00
func (cp *ConnectionPool) SafeGet() (PoolConnection, error) {
r, err := cp.pool.Get()
if err != nil {
return nil, err
}
return r.(*pooledConnection), nil
}
// You must call Recycle on the PoolConnection once done.
2013-04-11 02:43:10 +04:00
func (cp *ConnectionPool) TryGet() PoolConnection {
r, err := cp.pool.TryGet()
2012-02-25 11:30:03 +04:00
if err != nil {
panic(NewTabletErrorSql(FATAL, err))
2012-02-25 11:30:03 +04:00
}
if r == nil {
return nil
2012-02-25 11:30:03 +04:00
}
return r.(*pooledConnection)
2012-02-25 11:30:03 +04:00
}
func (cp *ConnectionPool) Put(conn PoolConnection) {
cp.pool.Put(conn)
}
func (cp *ConnectionPool) SetCapacity(capacity int) (err error) {
cp.mu.Lock()
defer cp.mu.Unlock()
err = cp.pool.SetCapacity(capacity)
if err != nil {
return err
}
cp.capacity = capacity
return nil
}
func (cp *ConnectionPool) SetIdleTimeout(idleTimeout time.Duration) {
cp.mu.Lock()
defer cp.mu.Unlock()
cp.pool.SetIdleTimeout(idleTimeout)
cp.idleTimeout = idleTimeout
}
func (cp *ConnectionPool) StatsJSON() string {
if cp.pool == nil {
return "{}"
}
return cp.pool.StatsJSON()
}
func (cp *ConnectionPool) Capacity() int64 {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.Capacity()
}
func (cp *ConnectionPool) Available() int64 {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.Available()
}
func (cp *ConnectionPool) MaxCap() int64 {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.MaxCap()
}
func (cp *ConnectionPool) WaitCount() int64 {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.WaitCount()
}
func (cp *ConnectionPool) WaitTime() time.Duration {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.WaitTime()
}
func (cp *ConnectionPool) IdleTimeout() time.Duration {
2013-08-12 22:31:08 +04:00
if cp.pool == nil {
return 0
}
return cp.pool.IdleTimeout()
}
// pooledConnection re-exposes DBConnection as a PoolConnection
type pooledConnection struct {
2012-03-21 04:33:11 +04:00
*DBConnection
pool *ConnectionPool
2012-02-25 11:30:03 +04:00
}
2013-04-11 02:43:10 +04:00
func (pc *pooledConnection) Recycle() {
if pc.IsClosed() {
pc.pool.Put(nil)
} else {
pc.pool.Put(pc)
}
2012-02-25 11:30:03 +04:00
}