go创建一个连接池

连接池

1 需要注册连接的方法
2 连接必须实现关闭方法
3 运行注册pool 
4 是否关闭
5 写连接池和关闭的时候加锁
6 接口的实现是区分*和非*的

具体实现代码

package workpool

import (
    "errors"
    "io"
    "log"
    "sync"
)

//创建连接的接口
type createConection interface {
    CreateConnect() (io.Closer, error)
}

//一个pool
type ConectPool struct {
    closeChan chan io.Closer
    factory   createConection
    isClose   bool
    mutex     sync.Mutex
}

//新建一个pool
func NewConnectPool(poolSize int, factory createConection) (*ConectPool, error) {
    if poolSize < 0 {
        return nil, errors.New("pool size  < 0")
    }

    return &ConectPool{
        closeChan: make(chan io.Closer, poolSize),
        factory:   factory,
        isClose:   false,
    }, nil
}

//获取连接
func (cp *ConectPool) GetConnect() (io.Closer, error) {
    select {

    case connect, ok := <-cp.closeChan:
        if !ok {
            return nil, errors.New("closeChan is closed")
        }
        log.Println("fetch connect sucessed")
        return connect, nil
    default:
        log.Println("fetch connect faild,create a new one")
        return cp.factory.CreateConnect()
    }
}

//把一个连接放入池子
func (cp *ConectPool) PutConnect(aConnection io.Closer) {
    cp.mutex.Lock()
    defer cp.mutex.Unlock()
    if cp.isClose == true {
        return
    }

    select {
    case cp.closeChan <- aConnection:
        log.Println("put connection into the closer!")
    default:
        log.Println("put faild.close connection!")
        aConnection.Close()
    }

}

//关闭连接
func (cp *ConectPool) Close() {
    cp.mutex.Lock()
    defer cp.mutex.Unlock()
    if cp.isClose != true {
        cp.isClose = true
    }
    close(cp.closeChan)
    for aConnect := range cp.closeChan {
        aConnect.Close()
    }
}

测试例子

//创建一个connect
var connectId int32 = 0

type DbConnect struct {
    cid int32
}

func (db *DbConnect) getConnectId() int32 {
    return db.cid
}

func (db *DbConnect) Close() error {
    return nil
}

//创建连接
type DbConnectCreater struct{}

func (dbc *DbConnectCreater) CreateConnect() (io.Closer, error) {

    id := atomic.AddInt32(&connectId, 1)

    return &DbConnect{cid: id}, nil
}

func tpool3() {
    fmt.Println("test connect pool3")
    creater := &DbConnectCreater{}
    pool3, err := workpool.NewConnectPool(10, creater)
    if err != nil {
        log.Println("create faild")
    }
    defer pool3.Close()
    //放入10个连接
    for i := 0; i < 10; i++ {
        conect, err := creater.CreateConnect()
        if err == nil {
            pool3.PutConnect(conect)
        }
    }

    for i := 0; i < 12; i++ {
        connect, err := pool3.GetConnect()
        if err == nil {
            log.Println("connect_id=", connect.(*DbConnect).getConnectId())

        }
    }

}

具体可以看这个 https://github.com/beckbikang/go_pool

猜你喜欢

转载自blog.csdn.net/cabing2005/article/details/78448373