mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
refactor: pool get options支持不创建连接
This commit is contained in:
@@ -49,7 +49,7 @@ func NewCachePool[T Conn](factory func() (T, error), opts ...Option[T]) *CachePo
|
||||
func (p *CachePool[T]) Get(ctx context.Context, opts ...GetOption) (T, error) {
|
||||
var zero T
|
||||
|
||||
options := getOptions{updateLastActive: true} // 默认更新 lastActive
|
||||
options := defaultGetOptions // 默认更新 lastActive
|
||||
for _, apply := range opts {
|
||||
apply(&options)
|
||||
}
|
||||
@@ -75,6 +75,10 @@ func (p *CachePool[T]) Get(ctx context.Context, opts ...GetOption) (T, error) {
|
||||
}
|
||||
p.mu.RUnlock()
|
||||
|
||||
if !options.newConn {
|
||||
return zero, ErrNoAvailableConn
|
||||
}
|
||||
|
||||
// 没有找到可用连接,升级为写锁进行创建
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
@@ -241,6 +245,7 @@ func (p *CachePool[T]) ping(conn T) bool {
|
||||
case <-done:
|
||||
return result
|
||||
case <-time.After(2 * time.Second): // 设置超时
|
||||
logx.Debug("ping timeout")
|
||||
return false // 超时认为不可用
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func (p *ChanPool[T]) Get(ctx context.Context, opts ...GetOption) (T, error) {
|
||||
connChan := make(chan T, 1)
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
options := getOptions{updateLastActive: true} // 默认更新 lastActive
|
||||
options := defaultGetOptions // 默认更新 lastActive
|
||||
for _, apply := range opts {
|
||||
apply(&options)
|
||||
}
|
||||
@@ -114,11 +114,11 @@ func (p *ChanPool[T]) Get(ctx context.Context, opts ...GetOption) (T, error) {
|
||||
}
|
||||
|
||||
func (p *ChanPool[T]) get(opts getOptions) (T, error) {
|
||||
var zero T
|
||||
// 检查连接池是否已关闭
|
||||
p.mu.RLock()
|
||||
if p.closed {
|
||||
p.mu.RUnlock()
|
||||
var zero T
|
||||
return zero, ErrPoolClosed
|
||||
}
|
||||
p.mu.RUnlock()
|
||||
@@ -133,6 +133,9 @@ func (p *ChanPool[T]) get(opts getOptions) (T, error) {
|
||||
}
|
||||
return wrapper.conn, nil
|
||||
default:
|
||||
if !opts.newConn {
|
||||
return zero, ErrNoAvailableConn
|
||||
}
|
||||
return p.createConn()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrPoolClosed = errors.New("pool is closed")
|
||||
var (
|
||||
ErrPoolClosed = errors.New("pool is closed")
|
||||
ErrNoAvailableConn = errors.New("no available connection")
|
||||
)
|
||||
|
||||
// PoolConfig 连接池配置
|
||||
type PoolConfig[T Conn] struct {
|
||||
@@ -71,11 +74,26 @@ type GetOption func(*getOptions)
|
||||
// 控制 Get 行为的选项
|
||||
type getOptions struct {
|
||||
updateLastActive bool // 是否更新 lastActive,默认 true
|
||||
newConn bool // 连接不存在时是否创建新连接,默认 true
|
||||
}
|
||||
|
||||
// WithNoUpdateLastActive 返回一个 Option,禁用更新 lastActive
|
||||
func WithNoUpdateLastActive() GetOption {
|
||||
var (
|
||||
defaultGetOptions = getOptions{
|
||||
updateLastActive: true,
|
||||
newConn: true,
|
||||
}
|
||||
)
|
||||
|
||||
// WithGetNoUpdateLastActive 返回一个 Option,禁用更新 lastActive
|
||||
func WithGetNoUpdateLastActive() GetOption {
|
||||
return func(o *getOptions) {
|
||||
o.updateLastActive = false
|
||||
}
|
||||
}
|
||||
|
||||
// WithGetNoCreateConn 禁用获取时连接不存在创建连接
|
||||
func WithGetNoNewConn() GetOption {
|
||||
return func(o *getOptions) {
|
||||
o.newConn = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,8 +117,8 @@ func (pg *PoolGroup[T]) asyncClose(pool Pool[T], key string) {
|
||||
select {
|
||||
case <-done:
|
||||
logx.Infof("pool group - pool closed successfully, key: %s", key)
|
||||
case <-time.After(5 * time.Second):
|
||||
logx.Errorf("pool group - pool close timeout, possible deadlock detected, key: %s", key)
|
||||
case <-time.After(10 * time.Second):
|
||||
logx.Errorf("pool group - pool close timeout, key: %s", key)
|
||||
// 打印当前 goroutine 的堆栈信息
|
||||
buf := make([]byte, 1<<16)
|
||||
runtime.Stack(buf, true)
|
||||
|
||||
Reference in New Issue
Block a user