mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
refactor: pool get options支持不创建连接
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@logicflow/core": "^2.0.13",
|
||||
"@logicflow/extension": "^2.0.18",
|
||||
"@vueuse/core": "^13.2.0",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/addon-search": "^0.15.0",
|
||||
"@xterm/addon-web-links": "^0.11.0",
|
||||
@@ -36,12 +36,12 @@
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.6",
|
||||
"splitpanes": "^4.0.3",
|
||||
"splitpanes": "^4.0.4",
|
||||
"sql-formatter": "^15.6.1",
|
||||
"trzsz": "^1.1.5",
|
||||
"uuid": "^9.0.1",
|
||||
"vue": "^3.5.14",
|
||||
"vue-i18n": "^11.1.3",
|
||||
"vue": "^3.5.16",
|
||||
"vue-i18n": "^11.1.5",
|
||||
"vue-router": "^4.5.1",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
@@ -54,16 +54,16 @@
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vue/compiler-sfc": "^3.5.14",
|
||||
"@vue/compiler-sfc": "^3.5.16",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"code-inspector-plugin": "^0.20.9",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^9.25.1",
|
||||
"eslint-plugin-vue": "^10.0.0",
|
||||
"postcss": "^8.5.3",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint-plugin-vue": "^10.1.0",
|
||||
"postcss": "^8.5.4",
|
||||
"prettier": "^3.5.3",
|
||||
"sass": "^1.89.0",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"tailwindcss": "^4.1.8",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.3.5",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
|
||||
@@ -19,7 +19,7 @@ type DataSyncTaskListVO struct {
|
||||
type DataSyncLogListVO struct {
|
||||
CreateTime *time.Time `json:"createTime"`
|
||||
DataSqlFull string `json:"dataSqlFull"`
|
||||
ResNum string `json:"resNum"`
|
||||
ResNum int `json:"resNum"`
|
||||
ErrText string `json:"errText"`
|
||||
Status *int `json:"status"`
|
||||
}
|
||||
|
||||
@@ -17,16 +17,6 @@ func InitIoc() {
|
||||
|
||||
func Init() {
|
||||
sync.OnceFunc(func() {
|
||||
//if err := GetDbBackupApp().Init(); err != nil {
|
||||
// panic(fmt.Sprintf("初始化 DbBackupApp 失败: %v", err))
|
||||
//}
|
||||
//if err := GetDbRestoreApp().Init(); err != nil {
|
||||
// panic(fmt.Sprintf("初始化 DbRestoreApp 失败: %v", err))
|
||||
//}
|
||||
//if err := GetDbBinlogApp().Init(); err != nil {
|
||||
// panic(fmt.Sprintf("初始化 DbBinlogApp 失败: %v", err))
|
||||
//}
|
||||
|
||||
GetDataSyncTaskApp().InitCronJob()
|
||||
GetDbTransferTaskApp().InitCronJob()
|
||||
GetDbTransferTaskApp().TimerDeleteTransferFile()
|
||||
|
||||
@@ -76,6 +76,7 @@ func (app *dataSyncAppImpl) Save(ctx context.Context, taskEntity *entity.DataSyn
|
||||
taskEntity.TaskKey = uuid.New().String()
|
||||
err = app.Insert(ctx, taskEntity)
|
||||
} else {
|
||||
taskEntity.TaskKey = ""
|
||||
err = app.UpdateById(ctx, taskEntity)
|
||||
}
|
||||
|
||||
@@ -107,15 +108,13 @@ func (app *dataSyncAppImpl) AddCronJob(ctx context.Context, taskEntity *entity.D
|
||||
// 根据状态添加新的任务
|
||||
if taskEntity.Status == entity.DataSyncTaskStatusEnable {
|
||||
taskId := taskEntity.Id
|
||||
logx.Infof("start add the data sync task job: %s, cron[%s]", taskEntity.TaskName, taskEntity.TaskCron)
|
||||
if err := scheduler.AddFunByKey(key, taskEntity.TaskCron, func() {
|
||||
logx.Infof("start the data synchronization task: %d", taskId)
|
||||
cancelCtx, cancelFunc := context.WithCancel(ctx)
|
||||
defer cancelFunc()
|
||||
if err := app.RunCronJob(cancelCtx, taskId); err != nil {
|
||||
logx.Errorf("the data synchronization task failed to execute at a scheduled time: %s", err.Error())
|
||||
if err := app.RunCronJob(context.Background(), taskId); err != nil {
|
||||
logx.Errorf("the data sync task failed to execute at a scheduled time: %s", err.Error())
|
||||
}
|
||||
}); err != nil {
|
||||
logx.ErrorTrace("add db data sync cron job failed", err)
|
||||
logx.ErrorTrace("add db data sync job failed", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,6 +132,9 @@ func (app *dataSyncAppImpl) RunCronJob(ctx context.Context, id uint64) error {
|
||||
if err != nil {
|
||||
return errorx.NewBiz("task not found")
|
||||
}
|
||||
|
||||
logx.InfofContext(ctx, "start the data sync task: %s => %s", task.TaskName, task.TaskKey)
|
||||
|
||||
if task.RunningState == entity.DataSyncTaskRunStateRunning {
|
||||
return errorx.NewBiz("the task is in progress")
|
||||
}
|
||||
@@ -140,8 +142,6 @@ func (app *dataSyncAppImpl) RunCronJob(ctx context.Context, id uint64) error {
|
||||
// 标记该任务运行中
|
||||
app.MarkRunning(id)
|
||||
|
||||
logx.InfofContext(ctx, "start the data synchronization task: %s => %s", task.TaskName, task.TaskKey)
|
||||
|
||||
go func() {
|
||||
// 通过占位符格式化sql
|
||||
updSql := ""
|
||||
|
||||
@@ -22,10 +22,7 @@ func init() {
|
||||
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||
items := poolGroup.AllPool()
|
||||
for _, v := range items {
|
||||
if v.Stats().TotalConns == 0 {
|
||||
continue // 连接池中没有连接,跳过
|
||||
}
|
||||
conn, err := v.Get(context.Background(), pool.WithNoUpdateLastActive())
|
||||
conn, err := v.Get(context.Background(), pool.WithGetNoUpdateLastActive(), pool.WithGetNoNewConn())
|
||||
if err != nil {
|
||||
continue // 获取连接失败,跳过
|
||||
}
|
||||
|
||||
@@ -45,10 +45,7 @@ func init() {
|
||||
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||
items := poolGroup.AllPool()
|
||||
for _, v := range items {
|
||||
if v.Stats().TotalConns == 0 {
|
||||
continue // 连接池中没有连接,跳过
|
||||
}
|
||||
conn, err := v.Get(context.Background(), pool.WithNoUpdateLastActive())
|
||||
conn, err := v.Get(context.Background(), pool.WithGetNoUpdateLastActive(), pool.WithGetNoNewConn())
|
||||
if err != nil {
|
||||
continue // 获取连接失败,跳过
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
type EsVersion string
|
||||
|
||||
type EsInfo struct {
|
||||
model.ExtraData // 连接需要的其他额外参数(json字符串),如oracle数据库需要指定sid等
|
||||
model.ExtraData // 连接需要的其他额外参数(json字符串)
|
||||
|
||||
InstanceId uint64 // 实例id
|
||||
Name string
|
||||
|
||||
@@ -53,10 +53,7 @@ func GetMachineCli(ctx context.Context, authCertName string, getMachine func(str
|
||||
// 删除指定机器缓存客户端,并关闭客户端连接
|
||||
func DeleteCli(id uint64) {
|
||||
for _, p := range poolGroup.AllPool() {
|
||||
if p.Stats().TotalConns == 0 {
|
||||
continue
|
||||
}
|
||||
conn, err := p.Get(context.Background(), pool.WithNoUpdateLastActive())
|
||||
conn, err := p.Get(context.Background(), pool.WithGetNoUpdateLastActive(), pool.WithGetNoNewConn())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ func init() {
|
||||
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||
items := poolGroup.AllPool()
|
||||
for _, v := range items {
|
||||
if v.Stats().TotalConns == 0 {
|
||||
continue // 连接池中没有连接,跳过
|
||||
}
|
||||
conn, err := v.Get(context.Background(), pool.WithNoUpdateLastActive())
|
||||
conn, err := v.Get(context.Background(), pool.WithGetNoUpdateLastActive(), pool.WithGetNoNewConn())
|
||||
if err != nil {
|
||||
continue // 获取连接失败,跳过
|
||||
}
|
||||
|
||||
@@ -174,8 +174,7 @@ func (r *redisAppImpl) Delete(ctx context.Context, id uint64) error {
|
||||
}
|
||||
// 如果存在连接,则关闭所有库连接信息
|
||||
for _, dbStr := range strings.Split(re.Db, ",") {
|
||||
db, _ := strconv.Atoi(dbStr)
|
||||
rdm.CloseConn(re.Id, db)
|
||||
rdm.CloseConn(re.Id, cast.ToInt(dbStr))
|
||||
}
|
||||
|
||||
return r.Tx(ctx, func(ctx context.Context) error {
|
||||
|
||||
@@ -15,10 +15,7 @@ func init() {
|
||||
// 遍历所有redis连接实例,若存在redis实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||||
items := poolGroup.AllPool()
|
||||
for _, v := range items {
|
||||
if v.Stats().TotalConns == 0 {
|
||||
continue // 连接池中没有连接,跳过
|
||||
}
|
||||
rc, err := v.Get(context.Background(), pool.WithNoUpdateLastActive())
|
||||
rc, err := v.Get(context.Background(), pool.WithGetNoUpdateLastActive(), pool.WithGetNoNewConn())
|
||||
if err != nil {
|
||||
continue // 获取连接失败,跳过
|
||||
}
|
||||
|
||||
@@ -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