Skip to content

Commit 2fdb170

Browse files
authored
feat: Database restore supports timeout settings (#11338)
1 parent 11764e1 commit 2fdb170

File tree

16 files changed

+75
-4
lines changed

16 files changed

+75
-4
lines changed

agent/app/dto/backup.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type CommonRecover struct {
8383
Secret string `json:"secret"`
8484
TaskID string `json:"taskID"`
8585
BackupRecordID uint `json:"backupRecordID"`
86+
Timeout int `json:"timeout"`
8687
}
8788

8889
type RecordSearch struct {

agent/app/service/backup_mysql.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,16 @@ func handleMysqlRecover(req dto.CommonRecover, parentTask *task.Task, isRollback
193193
return recoverDatabase(parentTask)
194194
}
195195

196-
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 0, 3*time.Hour)
196+
var timeout time.Duration
197+
switch req.Timeout {
198+
case -1:
199+
timeout = 0
200+
case 0:
201+
timeout = 3 * time.Hour
202+
default:
203+
timeout = time.Duration(req.Timeout) * time.Second
204+
}
205+
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 0, timeout)
197206
go func() {
198207
_ = itemTask.Execute()
199208
}()

agent/app/service/backup_postgresql.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,16 @@ func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRol
187187
return recoverDatabase(parentTask)
188188
}
189189

190-
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 0, 3*time.Hour)
190+
var timeout time.Duration
191+
switch req.Timeout {
192+
case -1:
193+
timeout = 0
194+
case 0:
195+
timeout = 3 * time.Hour
196+
default:
197+
timeout = time.Duration(req.Timeout) * time.Second
198+
}
199+
itemTask.AddSubTaskWithOps(i18n.GetMsgByKey("TaskRecover"), recoverDatabase, nil, 0, timeout)
191200
go func() {
192201
_ = itemTask.Execute()
193202
}()

agent/app/task/task.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ func (s *SubTask) Execute() error {
226226
s.RootTask.Log(i18n.GetWithName("TaskRetry", strconv.Itoa(i)))
227227
}
228228
ctx, cancel := context.WithTimeout(context.Background(), s.Timeout)
229+
if s.Timeout == 0 {
230+
ctx, cancel = context.WithCancel(context.Background())
231+
}
229232
defer cancel()
230233

231234
done := make(chan error)

frontend/src/components/backup/index.vue

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,22 @@
110110
<el-form-item :label="$t('setting.compressPassword')">
111111
<el-input v-model="secret" :placeholder="$t('setting.backupRecoverMessage')" />
112112
</el-form-item>
113+
<el-form-item
114+
v-if="!isBackup && type !== 'app' && type !== 'website'"
115+
:label="$t('cronjob.timeout')"
116+
prop="timeoutItem"
117+
>
118+
<el-input type="number" class="selectClass" v-model.number="timeoutItem">
119+
<template #append>
120+
<el-select v-model="timeoutUnit" style="width: 80px">
121+
<el-option :label="$t('commons.units.second')" value="s" />
122+
<el-option :label="$t('commons.units.minute')" value="m" />
123+
<el-option :label="$t('commons.units.hour')" value="h" />
124+
</el-select>
125+
</template>
126+
</el-input>
127+
<span class="input-help">{{ $t('database.recoverTimeoutHelper') }}</span>
128+
</el-form-item>
113129
<el-form-item v-if="isBackup" :label="$t('commons.table.description')">
114130
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 5 }" v-model="description" />
115131
</el-form-item>
@@ -133,7 +149,7 @@
133149

134150
<script lang="ts" setup>
135151
import { reactive, ref } from 'vue';
136-
import { computeSize, dateFormat, downloadFile, newUUID } from '@/utils/util';
152+
import { computeSize, dateFormat, downloadFile, newUUID, transferTimeToSecond } from '@/utils/util';
137153
import {
138154
getLocalBackupDir,
139155
handleBackup,
@@ -182,6 +198,8 @@ const backupPath = ref();
182198
const status = ref();
183199
const secret = ref();
184200
const description = ref();
201+
const timeoutItem = ref(30);
202+
const timeoutUnit = ref('m');
185203
186204
const open = ref();
187205
const isBackup = ref();
@@ -314,6 +332,7 @@ const recover = async (row?: any) => {
314332
secret: secret.value,
315333
taskID: taskID,
316334
backupRecordID: row.id,
335+
timeout: timeoutItem.value === -1 ? -1 : transferTimeToSecond(timeoutItem.value + timeoutUnit.value),
317336
};
318337
loading.value = true;
319338
await handleRecover(params)

frontend/src/components/upload/index.vue

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,22 @@
9494
<el-form-item :label="$t('setting.compressPassword')">
9595
<el-input v-model="secret" :placeholder="$t('setting.backupRecoverMessage')" />
9696
</el-form-item>
97+
<el-form-item
98+
v-if="type !== 'app' && type !== 'website'"
99+
:label="$t('cronjob.timeout')"
100+
prop="timeoutItem"
101+
>
102+
<el-input type="number" class="selectClass" v-model.number="timeoutItem">
103+
<template #append>
104+
<el-select v-model="timeoutUnit" style="width: 80px">
105+
<el-option :label="$t('commons.units.second')" value="s" />
106+
<el-option :label="$t('commons.units.minute')" value="m" />
107+
<el-option :label="$t('commons.units.hour')" value="h" />
108+
</el-select>
109+
</template>
110+
</el-input>
111+
<span class="input-help">{{ $t('database.recoverTimeoutHelper') }}</span>
112+
</el-form-item>
97113
</el-form>
98114
<template #footer>
99115
<span class="dialog-footer">
@@ -115,7 +131,7 @@
115131

116132
<script lang="ts" setup>
117133
import { reactive, ref } from 'vue';
118-
import { computeSize, newUUID } from '@/utils/util';
134+
import { computeSize, newUUID, transferTimeToSecond } from '@/utils/util';
119135
import i18n from '@/lang';
120136
import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile, genFileId } from 'element-plus';
121137
import { File } from '@/api/interface/file';
@@ -152,6 +168,8 @@ const name = ref();
152168
const detailName = ref();
153169
const remark = ref();
154170
const secret = ref();
171+
const timeoutItem = ref(30);
172+
const timeoutUnit = ref('m');
155173
const taskLogRef = ref();
156174
157175
const recoverDialog = ref();
@@ -261,6 +279,7 @@ const onHandleRecover = async () => {
261279
file: baseDir.value + currentRow.value.name,
262280
secret: secret.value,
263281
taskID: newUUID(),
282+
timeout: timeoutItem.value === -1 ? -1 : transferTimeToSecond(timeoutItem.value + timeoutUnit.value),
264283
};
265284
loading.value = true;
266285
await handleRecoverByUpload(params)

frontend/src/lang/modules/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ const message = {
513513
changeConnHelper: 'This operation will modify the current database {0}. Do you want to continue?',
514514
changePasswordHelper:
515515
'The database has been associated with an application. Changing the password will change the database password of the application at the same time. The change takes effect after the application restarts.',
516+
recoverTimeoutHelper: '-1 means no timeout limit',
516517

517518
confChange: 'Configuration',
518519
confNotFound:

frontend/src/lang/modules/es-es.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,8 @@ const message = {
517517
changeConnHelper: 'Esta operación modificará la base de datos actual {0}. ¿Desea continuar?',
518518
changePasswordHelper:
519519
'La base de datos ha sido asociada a una aplicación. Cambiar la contraseña también cambiará la contraseña de la base de datos en la aplicación. El cambio se aplica después de reiniciar la aplicación.',
520+
recoverTimeoutHelper: '-1 significa sin límite de tiempo de espera',
521+
520522
confChange: 'Configuración',
521523
confNotFound:
522524
'No se pudo encontrar el archivo de configuración. Por favor actualice la aplicación a la última versión en la tienda y vuelva a intentarlo.',

frontend/src/lang/modules/ja.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ const message = {
501501
changeConnHelper: 'この操作は現在のデータベース {0} を変更します。続行しますか?',
502502
changePasswordHelper:
503503
'データベースはアプリケーションに関連付けられています。パスワードを変更すると、アプリケーションのデータベースパスワードが同時に変更されます。アプリケーションが再起動した後、変更は有効になります。',
504+
recoverTimeoutHelper: '-1 はタイムアウト制限なしを意味します',
504505

505506
confChange: '構成',
506507
confNotFound:

frontend/src/lang/modules/ko.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ const message = {
504504
changeConnHelper: '이 작업은 현재 데이터베이스 {0}을(를) 수정합니다. 계속하시겠습니까?',
505505
changePasswordHelper:
506506
'데이터베이스가 애플리케이션과 연결되어 있습니다. 비밀번호를 변경하면 애플리케이션의 데이터베이스 비밀번호도 변경됩니다. 변경 사항은 애플리케이션이 재시작된 후에 적용됩니다.',
507+
recoverTimeoutHelper: '-1은 제한 시간 제한 없음을 의미합니다',
507508
confChange: '설정',
508509
confNotFound:
509510
'설정 파일을 찾을 수 없습니다. 앱 스토어에서 애플리케이션을 최신 버전으로 업그레이드하고 다시 시도해주세요!',

0 commit comments

Comments
 (0)