golang 基于channel封装资源池(可用于封装redis、mq连接池)
package pool
import (
"errors"
"io"
"sync"
"time"
) var (
ErrInvalidConfig = errors.New("invalid pool config")
ErrPoolClosed = errors.New("pool closed")
) type factory func() (io.Closer, error) type Pool interface {
Acquire() (io.Closer, error) // 获取资源
Release(io.Closer) error // 释放资源
Close(io.Closer) error // 关闭资源
Shutdown() error // 关闭池
} type GenericPool struct {
sync.Mutex
pool chan io.Closer
maxOpen int // 池中最大资源数
numOpen int // 当前池中资源数
minOpen int // 池中最少资源数
closed bool // 池是否已关闭
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
} // 释放单个资源到连接池
func (p *GenericPool) Release(closer io.Closer) error {
if p.closed {
return ErrPoolClosed
}
p.Lock()
p.pool <- closer
p.Unlock()
return nil
} // 关闭单个资源
func (p *GenericPool) Close(closer io.Closer) error {
p.Lock()
closer.Close()
p.numOpen--
p.Unlock()
return nil
} // 关闭连接池,释放所有资源
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
}
转:https://www.jb51.net/article/134302.htm
golang 基于channel封装资源池(可用于封装redis、mq连接池)的更多相关文章
- redis mysql 连接池 之 golang 实现
1 mysql 连接池代码 package lib import ( "database/sql" "fmt" "strconv" &quo ...
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
Go/Python/Erlang编程语言对比分析及示例 本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...
- 分享基于.NET动态编译&Newtonsoft.Json封装实现JSON转换器(JsonConverter)原理及JSON操作技巧
看文章标题就知道,本文的主题就是关于JSON,JSON转换器(JsonConverter)具有将C#定义的类源代码直接转换成对应的JSON字符串,以及将JSON字符串转换成对应的C#定义的类源代码,而 ...
- [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例)
[分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例) 踏雁寻花 发表于 2015-8-23 23:31:28 https://www.itsk.com/thread-35 ...
- Redisclient连接方式Hiredis简单封装使用,连接池、屏蔽连接细节
工作须要对Hiredis进行了简单封装,实现功能: 1.API进行统一,对外仅仅提供一个接口. 2.屏蔽上层应用对连接的细节处理: 3.底层採用队列的方式保持连接池,保存连接会话. 4.重连时採用时间 ...
- golang的channel实现
golang的channel实现位于src/runtime/chan.go文件.golang中的channel对应的结构是: // Invariants: // At least one of c.s ...
- Dapper的封装、二次封装、官方扩展包封装,以及ADO.NET原生封装
前几天偶然看到了dapper,由于以前没有用过,只用过ef core,稍微看了一下,然后写了一些简单的可复用的封装. Dapper的用法比较接近ADO.NET所以性能也是比较快.所以我们先来看看使用A ...
- SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装
SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...
- Spring NamedParameterJdbcTemplate命名参数查询条件封装, NamedParameterJdbcTemplate查询封装
Spring NamedParameterJdbcTemplate命名参数查询条件封装, NamedParameterJdbcTemplate查询封装 >>>>>> ...
随机推荐
- 小程序~列表渲染~key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/> 中的输入内容, <switch/> 的选中状态),需要 ...
- shortcuts for contructor 创建对象捷径
- QPS、TPS、PV、UV、IP
QPS TPS PV UV IP GMV RPS QPS.TPS.PV.UV.GMV.IP.RPS等各种名词,外行看起来很牛X,实际上每个程序员都是必懂知识点.下面我来一一解释一下. QPS Quer ...
- LINUX部署JAVA项目
Tomcat 应用服务器搭建好 安装 tomcat 所需依赖或工具软件 sudo yum -y update sudo yum -y install wget java unzip 使用 wget 下 ...
- django-购物车添加
商品详情页detail.html添加加入购物车按钮 <a href="javascript:;" sku_id="{{ sku.id }}" class= ...
- SQL Server 父子迭代查询语句,树状查询
这个也有用: -- Get childs by parent idWITH TreeAS( SELECT Id,ParentId FROM dbo.Node P WHERE P.Id = 21 -- ...
- BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列
code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...
- Linux 系统管理——账号管理
一.用户账号管理 1.用户账户概述 用户账户的常见分类: 超级用户:root uid=0 gid=0 权限最大 普通用户:uid>=500 做一般权限的系统管理,权限有限. 程序用户:1 ...
- AGC028 E - High Elements
AGC028 E - High Elements 有一个排列\(p\),你要分成两个子序列\(A,B\),满足\(A,B\)的LIS长度相等.设\(S\)是一个\(01\)序列,\(S_i=0\)当且 ...
- 坑:jmeter部署AWS云服务器时出现连接超时Non HTTP response code: org.apache.http.conn.HttpHostConnectException
背景: jmeter脚本部署到云服务器(AWS EC2)公网上时,启动jmeter脚本运行了5个小时才运行完毕,后面发现脚本报错timeout(如图),找了很久不知道原因,后面进入脚本发现全部在报错. ...