From 8542323c0b5f66f33f5b6f007e37b1d87282cbe3 Mon Sep 17 00:00:00 2001
From: ssongliu <73214554+ssongliu@users.noreply.github.com>
Date: Mon, 4 Aug 2025 13:40:35 +0800
Subject: [PATCH] fix: Add custom timeout support for remote database (#9830)
---
agent/app/dto/database.go | 2 ++
agent/app/service/backup_postgresql.go | 4 +--
agent/app/service/database.go | 28 +++++++++++--------
frontend/src/api/interface/database.ts | 3 ++
.../src/views/database/mysql/remote/index.vue | 2 ++
.../database/mysql/remote/operate/index.vue | 13 ++++++++-
6 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/agent/app/dto/database.go b/agent/app/dto/database.go
index 022f1b180..3f1ca975f 100644
--- a/agent/app/dto/database.go
+++ b/agent/app/dto/database.go
@@ -295,6 +295,7 @@ type DatabaseCreate struct {
ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"`
+ Timeout uint `json:"timeout"`
Description string `json:"description"`
}
@@ -313,6 +314,7 @@ type DatabaseUpdate struct {
ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"`
+ Timeout uint `json:"timeout"`
Description string `json:"description"`
}
diff --git a/agent/app/service/backup_postgresql.go b/agent/app/service/backup_postgresql.go
index 2a3b7ccc3..747621d4a 100644
--- a/agent/app/service/backup_postgresql.go
+++ b/agent/app/service/backup_postgresql.go
@@ -119,7 +119,7 @@ func handlePostgresqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir,
}
itemHandler := func() error { return doPostgresqlgBackup(db, targetDir, fileName) }
- backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeWebsite), func(task *task.Task) error { return itemHandler() }, nil)
+ backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(task *task.Task) error { return itemHandler() }, nil)
if parentTask != nil {
return itemHandler()
}
@@ -137,7 +137,7 @@ func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRol
}
itemTask = parentTask
if parentTask == nil {
- itemTask, err = task.NewTaskWithOps("Redis", task.TaskRecover, task.TaskScopeDatabase, req.TaskID, dbInfo.ID)
+ itemTask, err = task.NewTaskWithOps(req.Name, task.TaskRecover, task.TaskScopeDatabase, req.TaskID, dbInfo.ID)
if err != nil {
return err
}
diff --git a/agent/app/service/database.go b/agent/app/service/database.go
index b812d7a99..acd82a2ad 100644
--- a/agent/app/service/database.go
+++ b/agent/app/service/database.go
@@ -6,19 +6,17 @@ import (
"os"
"path"
- "github.com/1Panel-dev/1Panel/agent/app/repo"
-
- "github.com/1Panel-dev/1Panel/agent/utils/postgresql"
- pgclient "github.com/1Panel-dev/1Panel/agent/utils/postgresql/client"
- redisclient "github.com/1Panel-dev/1Panel/agent/utils/redis"
-
"github.com/1Panel-dev/1Panel/agent/app/dto"
+ "github.com/1Panel-dev/1Panel/agent/app/repo"
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/mysql"
"github.com/1Panel-dev/1Panel/agent/utils/mysql/client"
+ "github.com/1Panel-dev/1Panel/agent/utils/postgresql"
+ pgclient "github.com/1Panel-dev/1Panel/agent/utils/postgresql/client"
+ redisclient "github.com/1Panel-dev/1Panel/agent/utils/redis"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
)
@@ -118,6 +116,9 @@ func (u *DatabaseService) LoadItems(dbType string) ([]dto.DatabaseItem, error) {
}
func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
+ if req.Timeout == 0 {
+ req.Timeout = 30
+ }
switch req.Type {
case constant.AppPostgresql:
_, err := postgresql.NewPostgresqlClient(pgclient.DBInfo{
@@ -126,7 +127,7 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
Port: req.Port,
Username: req.Username,
Password: req.Password,
- Timeout: 6,
+ Timeout: req.Timeout,
})
return err == nil
case constant.AppRedis:
@@ -149,7 +150,7 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
ClientKey: req.ClientKey,
ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify,
- Timeout: 6,
+ Timeout: req.Timeout,
})
return err == nil
}
@@ -158,6 +159,9 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
}
func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
+ if req.Timeout == 0 {
+ req.Timeout = 30
+ }
db, _ := databaseRepo.Get(repo.WithByName(req.Name))
if db.ID != 0 {
if db.From == "local" {
@@ -173,7 +177,7 @@ func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
Port: req.Port,
Username: req.Username,
Password: req.Password,
- Timeout: 6,
+ Timeout: req.Timeout,
}); err != nil {
return err
}
@@ -198,7 +202,7 @@ func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
ClientKey: req.ClientKey,
ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify,
- Timeout: 6,
+ Timeout: req.Timeout,
}); err != nil {
return err
}
@@ -273,7 +277,7 @@ func (u *DatabaseService) Update(req dto.DatabaseUpdate) error {
Port: req.Port,
Username: req.Username,
Password: req.Password,
- Timeout: 300,
+ Timeout: req.Timeout,
}); err != nil {
return err
}
@@ -298,7 +302,7 @@ func (u *DatabaseService) Update(req dto.DatabaseUpdate) error {
ClientKey: req.ClientKey,
ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify,
- Timeout: 300,
+ Timeout: req.Timeout,
}); err != nil {
return err
}
diff --git a/frontend/src/api/interface/database.ts b/frontend/src/api/interface/database.ts
index fd69c224b..f1f92285b 100644
--- a/frontend/src/api/interface/database.ts
+++ b/frontend/src/api/interface/database.ts
@@ -283,6 +283,7 @@ export namespace Database {
clientCert: string;
skipVerify: boolean;
+ timeout: number;
description: string;
}
export interface SearchDatabasePage {
@@ -322,6 +323,7 @@ export namespace Database {
clientCert: string;
skipVerify: boolean;
+ timeout: number;
description: string;
}
export interface DatabaseUpdate {
@@ -338,6 +340,7 @@ export namespace Database {
clientCert: string;
skipVerify: boolean;
+ timeout: number;
description: string;
}
export interface DatabaseDelete {
diff --git a/frontend/src/views/database/mysql/remote/index.vue b/frontend/src/views/database/mysql/remote/index.vue
index 21c0a0387..27f152014 100644
--- a/frontend/src/views/database/mysql/remote/index.vue
+++ b/frontend/src/views/database/mysql/remote/index.vue
@@ -126,6 +126,7 @@ const onOpenDialog = async (
port: 3306,
username: 'root',
password: '',
+ timeout: 30,
description: '',
},
) => {
@@ -133,6 +134,7 @@ const onOpenDialog = async (
title,
rowData: { ...rowData },
};
+ params.rowData.timeout = 30;
dialogRef.value!.acceptParams(params);
};
diff --git a/frontend/src/views/database/mysql/remote/operate/index.vue b/frontend/src/views/database/mysql/remote/operate/index.vue
index ab433abbf..136a1f003 100644
--- a/frontend/src/views/database/mysql/remote/operate/index.vue
+++ b/frontend/src/views/database/mysql/remote/operate/index.vue
@@ -87,6 +87,16 @@
+
+
+
@@ -111,7 +121,7 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { Database } from '@/api/interface/database';
import { MsgError, MsgSuccess } from '@/utils/message';
-import { Rules } from '@/global/form-rules';
+import { checkNumberRange, Rules } from '@/global/form-rules';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';
interface DialogProps {
@@ -159,6 +169,7 @@ const rules = reactive({
port: [Rules.port],
username: [Rules.requiredInput],
password: [Rules.requiredInput],
+ timeout: [Rules.number, checkNumberRange(1, 600)],
});
type FormInstance = InstanceType;