go实现连接池

还未测试的连接池。。。

只是暂时写出来。。。

package adapter

import (
	"container/list"
	"errors"
	"net"
	"sync"
)

// 状态
const (
	runing = iota
	idle
)

const (
	error_no_tcp     = "no tcp"
	error_dial_error = "Dial() is error"
)

type Remote struct {
	conn   net.Conn // 连接
	status int      // 连接的状态
}

//
// 释放tcp(不关闭),只是将它的状态改为idle,便于下次使用
//
func (this *Remote) Release() {
	this.status = idle
}

type RemotePool struct {
	pool *list.List
	mu   sync.Mutex

	Dial func() (interface{}, error)
}

//
//  获取一个有效的连接\
//    没有则返回nil
//
func (this *RemotePool) Get() (remote *Remote, err error) {
	this.mu.Lock()
	defer this.mu.Unlock()

	if this.pool == nil {
		// 初始化
		this.pool = list.New()
		conn, err := this.Dial()
		if err != nil {
			return nil, errors.New(error_dial_error)
		}
		remote := &Remote{
			conn:   conn.(net.Conn),
			status: idle,
		}
		this.pool.PushBack(remote)
	}

	for e := this.pool.Front(); e != nil; e = e.Next() {
		r := e.Value.(Remote)
		if r.status == idle {
			r.status = runing
			return &r, nil
		}
	}
	return nil, errors.New(error_no_tcp)
}

//
// 用完的tcp连接丢到连接中
//
func (this *RemotePool) Put(conn net.Conn) {
	this.mu.Lock()
	defer this.mu.Unlock()

	remote := &Remote{
		conn:   conn,
		status: idle,
	}

	// 插到最前面,减少Get()时的循环
	this.pool.PushFront(remote)
}

//
//  删除tcp连接
//
func (this *RemotePool) Close(remote *Remote) {
	this.mu.Lock()
	defer this.mu.Unlock()

	if remote == nil {
		return
	}

	for e := this.pool.Front(); e != nil; e = e.Next() {
		if e.Value.(Remote).conn == remote.conn {
			if remote.conn != nil {
				remote.conn.Close()
			}
			this.pool.Remove(e)
			return
		}
	}
}

 

转载于:https://my.oschina.net/moli/blog/718754

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值