refactor(redis): remove redundant CLI status tracking

This commit is contained in:
guoyuqi
2026-10-09 18:03:11 +08:00
parent 22abdf9e79
commit c6e0b61720
21 changed files with 12 additions and 223 deletions
+1 -8
View File
@@ -484,10 +484,6 @@ func (u *ContainerService) LoadResourceLimit() (*dto.ResourceLimit, error) {
}
func (u *ContainerService) ContainerCreate(req dto.ContainerOperate, inThread bool) error {
return u.containerCreate(req, inThread, "")
}
func (u *ContainerService) containerCreate(req dto.ContainerOperate, inThread bool, taskName string) error {
client, err := docker.NewDockerClient()
if err != nil {
return err
@@ -501,10 +497,7 @@ func (u *ContainerService) containerCreate(req dto.ContainerOperate, inThread bo
return buserr.New("ErrContainerName")
}
if taskName == "" {
taskName = task.GetTaskName(req.Name, task.TaskCreate, task.TaskScopeContainer)
}
taskItem, err := task.NewTask(taskName, task.TaskCreate, task.TaskScopeContainer, req.TaskID, 1)
taskItem, err := task.NewTaskWithOps(req.Name, task.TaskCreate, task.TaskScopeContainer, req.TaskID, 1)
if err != nil {
unlock()
_ = client.Close()
-1
View File
@@ -43,7 +43,6 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/redis/status", baseApi.LoadRedisStatus)
cmdRouter.POST("/redis/conf", baseApi.LoadRedisConf)
cmdRouter.GET("/redis/check", baseApi.CheckHasCli)
cmdRouter.GET("/redis/cli/status", baseApi.LoadRedisCliStatus)
cmdRouter.POST("/redis/install/cli", baseApi.InstallCli)
cmdRouter.POST("/redis/password", baseApi.ChangeRedisPassword)
cmdRouter.POST("/redis/conf/update", baseApi.UpdateRedisConf)
-24
View File
@@ -15010,30 +15010,6 @@ const docTemplate = `{
]
}
},
"/databases/redis/cli/status": {
"get": {
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.RedisCliStatus"
}
}
},
"security": [
{
"ApiKeyAuth": []
},
{
"Timestamp": []
}
],
"summary": "Load redis-cli installation status",
"tags": [
"Database Redis"
]
}
},
"/databases/redis/conf": {
"post": {
"consumes": [
-24
View File
@@ -15006,30 +15006,6 @@
]
}
},
"/databases/redis/cli/status": {
"get": {
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.RedisCliStatus"
}
}
},
"security": [
{
"ApiKeyAuth": []
},
{
"Timestamp": []
}
],
"summary": "Load redis-cli installation status",
"tags": [
"Database Redis"
]
}
},
"/databases/redis/conf": {
"post": {
"consumes": [
+6 -12
View File
@@ -118,9 +118,7 @@ class RequestHttp {
}
if (data.code && data.code !== ResultEnum.SUCCESS) {
if (data.message.toLowerCase().indexOf('operation not permitted') !== -1) {
if (!(response.config as RequestConfig).skipErrorMessage) {
MsgError(i18n.global.t('license.tamperHelper'));
}
MsgError(i18n.global.t('license.tamperHelper'));
return Promise.reject(data);
}
if (!(response.config as RequestConfig).skipErrorMessage) {
@@ -132,10 +130,8 @@ class RequestHttp {
},
async (error: AxiosError) => {
const { response } = error;
const silent = (error.config as RequestConfig)?.skipErrorMessage;
if (!silent && error.message.indexOf('timeout') !== -1)
MsgError(i18n.global.t('commons.msg.requestTimeout'));
if (error.message.indexOf('timeout') !== -1) MsgError(i18n.global.t('commons.msg.requestTimeout'));
if (response) {
switch (response.status) {
case 313:
@@ -145,7 +141,6 @@ class RequestHttp {
if (isCsrfForbidden(response)) {
return Promise.reject(error);
}
if (silent) return Promise.reject(error);
if (response.data && response.data['message']) {
MsgError(response.data['message']);
} else {
@@ -156,11 +151,10 @@ class RequestHttp {
case 502:
case 524:
case 407:
if (!silent)
checkStatus(
response.status,
response.data && response.data['message'] ? response.data['message'] : '',
);
checkStatus(
response.status,
response.data && response.data['message'] ? response.data['message'] : '',
);
return Promise.reject(error);
default:
return Promise.reject(error);
-7
View File
@@ -1,13 +1,6 @@
import { ReqPage } from '.';
export namespace Database {
export interface RedisCliStatus {
installed: boolean;
taskID: string;
status: string;
errorMsg: string;
}
export interface SearchDBWithPage {
info: string;
database: string;
+2 -6
View File
@@ -190,12 +190,8 @@ export const redisPersistenceConf = (type: string, database: string) => {
name: database,
});
};
export const loadRedisCliStatus = (node: string) => {
return http.get<Database.RedisCliStatus>(
`/databases/redis/cli/status?operateNode=${encodeURIComponent(node)}`,
undefined,
{ skipErrorMessage: true },
);
export const checkRedisCli = () => {
return http.get<boolean>(`/databases/redis/check`);
};
export const installRedisCli = (taskID: string, node: string) => {
return http.post<string>(`/databases/redis/install/cli?operateNode=${encodeURIComponent(node)}`, {
-5
View File
@@ -739,11 +739,6 @@ const message = {
keyspaceMisses: 'Number of failed attempts to find the database key.',
hit: 'Find the database key hit ratio.',
latestForkUsec: 'The number of microseconds spent on the last fork() operation.',
redisCliEnableTask: 'Enable remote Redis terminal',
redisCliEnabling: 'Enabling remote Redis terminal',
redisCliEnabled: 'Remote Redis terminal enabled',
redisCliEnableFailed: 'Failed to enable remote Redis terminal. Check the task log and retry.',
redisCliTaskSubmitted: 'Task submitted. View progress in the task center.',
redisCliHelper: '"redis-cli" not detected. Enable the service first.',
redisQuickCmd: 'Redis quick commands',
recoverHelper: 'This will overwrite data with [{0}]. Continue?',
-6
View File
@@ -742,12 +742,6 @@ const message = {
keyspaceMisses: 'Cantidad de intentos fallidos para encontrar la clave.',
hit: 'Proporción de aciertos de clave de la base de datos.',
latestForkUsec: 'Microsegundos consumidos en la última operación fork().',
redisCliEnableTask: 'Habilitar terminal remoto de Redis',
redisCliEnabling: 'Habilitando terminal remoto de Redis',
redisCliEnabled: 'Terminal remoto de Redis habilitado',
redisCliEnableFailed:
'No se pudo habilitar el terminal remoto de Redis. Revise el registro de la tarea y vuelva a intentarlo.',
redisCliTaskSubmitted: 'Tarea enviada. Consulte el progreso en el centro de tareas.',
redisCliHelper: 'No se detectó el servicio "redis-cli". Primero habilite el servicio.',
redisQuickCmd: 'Comandos rápidos de Redis',
recoverHelper: 'Esto sobrescribirá los datos con [{0}]. ¿Desea continuar?',
-5
View File
@@ -734,11 +734,6 @@ const message = {
keyspaceMisses: 'تعداد دفعات ناموفق در یافتن کلید پایگاه داده.',
hit: 'نسبت برخورد کلید پایگاه داده.',
latestForkUsec: 'تعداد میکروثانیه‌های صرف شده برای آخرین عملیات fork().',
redisCliEnableTask: 'فعال‌سازی ترمینال راه دور Redis',
redisCliEnabling: 'در حال فعال‌سازی ترمینال راه دور Redis',
redisCliEnabled: 'ترمینال راه دور Redis فعال شد',
redisCliEnableFailed: 'فعال‌سازی ترمینال راه دور Redis ناموفق بود. لاگ وظیفه را بررسی کرده و دوباره تلاش کنید.',
redisCliTaskSubmitted: 'وظیفه ارسال شد. پیشرفت را در مرکز وظایف مشاهده کنید.',
redisCliHelper: '"redis-cli" شناسایی نشد. ابتدا سرویس را فعال کنید.',
redisQuickCmd: 'دستورات سریع Redis',
recoverHelper: 'این کار داده‌ها را با [{0}] بازنویسی می‌کند. ادامه می‌دهید؟',
-6
View File
@@ -739,12 +739,6 @@ const message = {
keyspaceMisses: 'データベースキーを見つけようとする試みの失敗の数。',
hit: 'データベースキーヒット率を見つけます。',
latestForkUsec: '最後のfork()操作に費やされたマイクロ秒数。',
redisCliEnableTask: 'Redis リモートターミナルを有効化',
redisCliEnabling: 'Redis リモートターミナルを有効化中',
redisCliEnabled: 'Redis リモートターミナルが有効になりました',
redisCliEnableFailed:
'Redis リモートターミナルの有効化に失敗しました。タスクログを確認して再試行してください。',
redisCliTaskSubmitted: 'タスクを送信しました。タスクセンターで進捗を確認できます。',
redisCliHelper: '「Redis-Cli」サービスは検出されません。最初にサービスを有効にします。',
redisQuickCmd: 'Redis Quickコマンド',
recoverHelper: 'これにより、[{0}]でデータが上書きされます。続けたいですか?',
-5
View File
@@ -730,11 +730,6 @@ const message = {
keyspaceMisses: '데이터베이스 키를 찾지 못한 횟수.',
hit: '데이터베이스 키 발견 비율.',
latestForkUsec: '마지막 fork() 작업에 소요된 마이크로초 수.',
redisCliEnableTask: 'Redis 원격 터미널 활성화',
redisCliEnabling: 'Redis 원격 터미널 활성화 중',
redisCliEnabled: 'Redis 원격 터미널이 활성화되었습니다',
redisCliEnableFailed: 'Redis 원격 터미널을 활성화하지 못했습니다. 작업 로그를 확인하고 다시 시도하십시오.',
redisCliTaskSubmitted: '작업이 제출되었습니다. 작업 센터에서 진행 상황을 확인하십시오.',
redisCliHelper: '"redis-cli" 서비스가 감지되지 않았습니다. 서비스를 먼저 활성화하십시오.',
redisQuickCmd: 'Redis 빠른 명령',
recoverHelper: '이 작업은 데이터를 [{0}]으로 덮어씁니다. 계속하시겠습니까?',
-5
View File
@@ -729,11 +729,6 @@ const message = {
keyspaceMisses: 'ຈຳນວນຄັ້ງທີ່ຄົ້ນຫາຄີໃນຖານຂໍ້ມູນຫຼົ້ມເຫຼວ.',
hit: 'ອັດຕາການຄົ້ນຫາຄີໃນຖານຂໍ້ມູນສຳເລັດ.',
latestForkUsec: 'ຈຳນວນໄມໂຄຣວິນາທີທີ່ໃຊ້ໃນການ fork() ລ່າສຸດ.',
redisCliEnableTask: 'ເປີດໃຊ້ເທີມິນອນ Redis ທາງໄກ',
redisCliEnabling: 'ກຳລັງເປີດໃຊ້ເທີມິນອນ Redis ທາງໄກ',
redisCliEnabled: 'ເປີດໃຊ້ເທີມິນອນ Redis ທາງໄກແລ້ວ',
redisCliEnableFailed: 'ເປີດໃຊ້ເທີມິນອນ Redis ທາງໄກບໍ່ສຳເລັດ. ກະລຸນາກວດເບິ່ງບັນທຶກໜ້າວຽກ ແລະ ລອງໃໝ່.',
redisCliTaskSubmitted: 'ສົ່ງໜ້າວຽກແລ້ວ. ສາມາດເບິ່ງຄວາມຄືບໜ້າໄດ້ໃນສູນໜ້າວຽກ.',
redisCliHelper: 'ບໍ່ພົບ "redis-cli". ກະລຸນາເປີດໃຊ້ບໍລິການກ່ອນ.',
redisQuickCmd: 'ຄຳສັ່ງ Redis ແບບດ່ວນ',
recoverHelper: 'ການດຳເນີນການນີ້ຈະຂຽນທັບຂໍ້ມູນດ້ວຍ [{0}]. ຕ້ອງການຕໍ່ຫຼືບໍ່?',
-5
View File
@@ -748,11 +748,6 @@ const message = {
keyspaceMisses: 'Bilangan percubaan gagal untuk mencari kunci pangkalan data.',
hit: 'Nisbah pencarian kunci pangkalan data yang berjaya.',
latestForkUsec: 'Bilangan mikrodetik yang dihabiskan pada operasi fork() terakhir.',
redisCliEnableTask: 'Aktifkan terminal Redis jauh',
redisCliEnabling: 'Sedang mengaktifkan terminal Redis jauh',
redisCliEnabled: 'Terminal Redis jauh telah diaktifkan',
redisCliEnableFailed: 'Gagal mengaktifkan terminal Redis jauh. Semak log tugas dan cuba lagi.',
redisCliTaskSubmitted: 'Tugas telah dihantar. Lihat kemajuan di pusat tugas.',
redisCliHelper: '"redis-cli" perkhidmatan tidak dikesan. Aktifkan perkhidmatan terlebih dahulu.',
redisQuickCmd: 'Arahan pantas Redis',
recoverHelper: 'Ini akan menimpa data dengan [{0}]. Adakah anda mahu meneruskan?',
-6
View File
@@ -741,12 +741,6 @@ const message = {
keyspaceMisses: 'Número de tentativas falhas de encontrar a chave do banco de dados.',
hit: 'Taxa de acerto de chave de banco de dados.',
latestForkUsec: 'Número de microssegundos gastos na última operação fork()',
redisCliEnableTask: 'Habilitar terminal remoto do Redis',
redisCliEnabling: 'Habilitando terminal remoto do Redis',
redisCliEnabled: 'Terminal remoto do Redis habilitado',
redisCliEnableFailed:
'Falha ao habilitar o terminal remoto do Redis. Verifique o log da tarefa e tente novamente.',
redisCliTaskSubmitted: 'Tarefa enviada. Acompanhe o progresso na central de tarefas.',
redisCliHelper: '"redis-cli" não foi detectado. Habilite o serviço primeiro.',
redisQuickCmd: 'Comandos rápidos Redis',
recoverHelper: 'Isso sobrescreverá os dados com [{0}]. Deseja continuar?',
-6
View File
@@ -736,12 +736,6 @@ const message = {
keyspaceMisses: 'Количество неудачных попыток найти ключ в базе данных.',
hit: 'Коэффициент попаданий при поиске ключей.',
latestForkUsec: 'Количество микросекунд, затраченных на последнюю операцию fork().',
redisCliEnableTask: 'Включить удалённый терминал Redis',
redisCliEnabling: 'Включение удалённого терминала Redis',
redisCliEnabled: 'Удалённый терминал Redis включён',
redisCliEnableFailed:
'Не удалось включить удалённый терминал Redis. Проверьте журнал задачи и повторите попытку.',
redisCliTaskSubmitted: 'Задача отправлена. Следите за ходом выполнения в центре задач.',
redisCliHelper: 'Сервис "redis-cli" не обнаружен. Сначала включите сервис.',
redisQuickCmd: 'Быстрые команды Redis',
recoverHelper: 'Это перезапишет данные с [{0}]. Хотите продолжить?',
-5
View File
@@ -743,11 +743,6 @@ const message = {
keyspaceMisses: 'Veritabanı anahtarını bulma girişimlerinin başarısız olma sayısı.',
hit: 'Veritabanı anahtarı isabet oranı.',
latestForkUsec: 'Son fork() işleminde harcanan mikrosaniye sayısı.',
redisCliEnableTask: 'Uzak Redis terminalini etkinleştir',
redisCliEnabling: 'Uzak Redis terminali etkinleştiriliyor',
redisCliEnabled: 'Uzak Redis terminali etkinleştirildi',
redisCliEnableFailed: 'Uzak Redis terminali etkinleştirilemedi. Görev günlüğünü kontrol edip tekrar deneyin.',
redisCliTaskSubmitted: 'Görev gönderildi. İlerlemeyi görev merkezinden takip edebilirsiniz.',
redisCliHelper: '"redis-cli" servisi algılanmadı. Önce servisi etkinleştirin.',
redisQuickCmd: 'Redis hızlı komutları',
recoverHelper: 'Bu işlem verileri [{0}] ile üzerine yazacak. Devam etmek istiyor musunuz?',
-5
View File
@@ -709,11 +709,6 @@ const message = {
keyspaceMisses: '尋找資料庫鍵失敗的次數',
hit: '尋找資料庫鍵命中率',
latestForkUsec: '最近一次 fork() 操作耗費的微秒數',
redisCliEnableTask: '啟用 Redis 遠端終端',
redisCliEnabling: '正在啟用 Redis 遠端終端',
redisCliEnabled: 'Redis 遠端終端已啟用',
redisCliEnableFailed: 'Redis 遠端終端啟用失敗,請查看任務日誌後重試',
redisCliTaskSubmitted: '啟用任務已提交,可在任務中心查看進度',
redisCliHelper: '未偵測到 redis-cli 服務,請先啟用服務',
redisQuickCmd: 'Redis 快速指令',
recoverHelper: '即將使用 [{0}] 對資料進行覆蓋,是否繼續?',
-5
View File
@@ -722,11 +722,6 @@ const message = {
keyspaceMisses: '查找数据库键失败的次数',
hit: '查找数据库键命中率',
latestForkUsec: '最近一次 fork() 操作耗费的微秒数',
redisCliEnableTask: '启用 Redis 远程终端',
redisCliEnabling: '正在启用 Redis 远程终端',
redisCliEnabled: 'Redis 远程终端已启用',
redisCliEnableFailed: 'Redis 远程终端启用失败,请查看任务日志后重试',
redisCliTaskSubmitted: '启用任务已提交,可在任务中心查看进度',
redisCliHelper: '未检测到 redis-cli 服务,请先启用服务!',
redisQuickCmd: 'Redis 快速命令',
-1
View File
@@ -24,7 +24,6 @@ const formatSkillInstallTask = () => {
};
const taskTextMap: Record<string, () => string> = {
RedisCliEnable: () => i18n.global.t('database.redisCliEnableTask'),
BatchInstallAgent: () => formatBatchAgentTask('Install'),
DispatchAgentInstallTasks: () => formatDispatchAgentTask('Install'),
BatchUpgradeAgent: () => formatBatchAgentTask('Upgrade'),
+3 -76
View File
@@ -150,10 +150,10 @@ import Conn from '@/views/database/redis/conn/index.vue';
import Terminal from '@/components/terminal/index.vue';
import AppStatus from '@/components/app-status/index.vue';
import QuickCmd from '@/views/database/redis/command/index.vue';
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
import { checkAppInstalled } from '@/api/modules/app';
import { useGlobalStore } from '@/composables/useGlobalStore';
import { listDatabases, loadRedisCliStatus, installRedisCli } from '@/api/modules/database';
import { listDatabases, checkRedisCli, installRedisCli } from '@/api/modules/database';
import { Database } from '@/api/interface/database';
import i18n from '@/lang';
import { getCommandList } from '@/api/modules/command';
@@ -261,7 +261,6 @@ const changeDatabase = async () => {
};
const loadDBOptions = async () => {
const generation = cliGeneration;
try {
const res = await listDatabases('redis,redis-cluster');
if (disposed || operateNode !== currentNode.value) return;
@@ -308,7 +307,7 @@ const loadDBOptions = async () => {
const loadErrMsg = () => {
return currentDB.value.from === 'local'
? i18n.global.t('commons.service.serviceNotStarted', ['Redis'])
: cliStatusText.value;
: i18n.global.t('database.redisCliHelper');
};
const reOpenTerminal = async () => {
closeTerminal(false);
@@ -374,57 +373,6 @@ const closeTerminal = async (isKeepShow: boolean) => {
terminalShow.value = isKeepShow;
};
const openCliTaskLog = () => {
if (cliTaskID.value) cliTaskLogRef.value?.openWithTaskID(cliTaskID.value, cliInstalling.value, currentNode.value);
};
const applyCliStatus = (status: Database.RedisCliStatus) => {
const wasInstalling = cliInstalling.value;
const wasReady = redisCliExist.value && !wasInstalling;
redisCliExist.value = status.installed;
cliTaskID.value = status.taskID;
cliTaskStatus.value = status.status;
cliStatusLoaded.value = true;
if (!wasReady && status.installed && !cliInstalling.value && currentDB.value?.from === 'remote') {
reOpenTerminal();
}
if (wasInstalling && !cliInstalling.value) {
bus.emit('refreshTask', true);
if (status.status === 'Success' && status.installed) {
MsgSuccess(i18n.global.t('database.redisCliEnabled'));
} else if (status.status === 'Failed') {
MsgError(i18n.global.t('database.redisCliEnableFailed'));
}
}
};
const scheduleCliPoll = (generation: number, delay = 2000) => {
clearTimeout(cliPollTimer);
if (disposed || generation !== cliGeneration) return;
cliPollTimer = setTimeout(() => refreshCliStatus(generation), delay);
};
const refreshCliStatus = async (generation: number) => {
try {
const res = await loadRedisCliStatus(currentNode.value);
if (disposed || generation !== cliGeneration) return;
cliPollFailures = 0;
cliPollFailed.value = false;
applyCliStatus(res.data);
if (cliInstalling.value) scheduleCliPoll(generation);
} catch (error) {
if (disposed || generation !== cliGeneration) return;
const status = error?.response?.status ?? error?.code;
// Only retry network errors, rate limiting and server errors.
const retryable = !Number.isFinite(status) || status === 429 || status >= 500;
if (retryable && ++cliPollFailures <= 5) {
scheduleCliPoll(generation, Math.min(2000 * 2 ** (cliPollFailures - 1), 30000));
} else {
cliPollFailed.value = true;
}
}
};
const checkCliValid = async () => {
if (disposed || operateNode !== currentNode.value) return;
try {
@@ -468,27 +416,6 @@ const onSetQuickCmd = () => {
dialogQuickCmdRef.value.acceptParams();
};
watch(currentNode, () => {
cliGeneration++;
clearTimeout(cliPollTimer);
cliTaskLogRef.value?.handleClose();
closeTerminal(false);
redisCliExist.value = false;
cliSubmitting.value = false;
cliStatusLoaded.value = false;
cliPollFailed.value = false;
cliPollFailures = 0;
cliTaskID.value = '';
cliTaskStatus.value = '';
currentDB.value = undefined;
redisStatus.value = undefined;
dbOptionsLocal.value = [];
dbOptionsRemote.value = [];
isLoaded.value = false;
loading.value = false;
checkCliValid();
});
onMounted(() => {
loadQuickCmd();
checkCliValid();