diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index cb8cca5f..f0dc0efc 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -22,14 +22,14 @@ export default async () => { ); // 初始化时安装所有处于安装中,安装成功,安装失败的依赖 - dependenceDb.find({ status: { $in: [0, 1, 2] } }).exec((err, docs) => { + dependenceDb.find({ status: { $in: [0, 1, 2] } }).exec(async (err, docs) => { const groups = _.groupBy(docs, 'type'); for (const key in groups) { if (Object.prototype.hasOwnProperty.call(groups, key)) { const group = groups[key]; const depIds = group.map((x) => x._id); for (const dep of depIds) { - dependenceService.reInstall([dep]); + await dependenceService.reInstall([dep]); } } } diff --git a/back/services/cron.ts b/back/services/cron.ts index 7f9b9e67..f51943c8 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -245,16 +245,20 @@ export default class CronService { } else { return; } - const pids = pid.match(/\(\d+/g); + let pids = pid.match(/\(\d+/g); const killLogs = []; - for (const id of pids) { - const c = `kill -9 ${id.slice(1)}`; - const { stdout, stderr } = await execAsync(c); - if (stderr) { - killLogs.push(stderr); - } - if (stdout) { - killLogs.push(stdout); + if (pids && pids.length > 0) { + // node 执行脚本时还会有10个子进程,但是ps -ef中不存在,所以截取前三个 + pids = pids.slice(0, 3); + for (const id of pids) { + const c = `kill -9 ${id.slice(1)}`; + const { stdout, stderr } = await execAsync(c); + if (stderr) { + killLogs.push(stderr); + } + if (stdout) { + killLogs.push(stdout); + } } } return killLogs.length > 0 ? JSON.stringify(killLogs) : ''; diff --git a/back/services/dependence.ts b/back/services/dependence.ts index f6a213b1..5cb95bc3 100644 --- a/back/services/dependence.ts +++ b/back/services/dependence.ts @@ -131,7 +131,7 @@ export default class DependenceService { { $set: { status: DependenceStatus.installing, log: [] } }, { multi: true, returnUpdatedDocs: true }, async (err, num, docs: Dependence[]) => { - this.installOrUninstallDependencies(docs); + await this.installOrUninstallDependencies(docs); resolve(docs); }, ); @@ -178,103 +178,109 @@ export default class DependenceService { dependencies: Dependence[], isInstall: boolean = true, ) { - if (dependencies.length === 0) { - return; - } - const depNames = dependencies.map((x) => x.name).join(' '); - const depRunCommand = ( - isInstall - ? InstallDependenceCommandTypes - : unInstallDependenceCommandTypes - )[dependencies[0].type as any]; - const actionText = isInstall ? '安装' : '删除'; - const depIds = dependencies.map((x) => x._id) as string[]; - const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' }); - const startTime = Date.now(); - this.sockService.sendMessage({ - type: 'installDependence', - message: `开始${actionText}依赖 ${depNames},开始时间 ${new Date( - startTime, - ).toLocaleString()}`, - references: depIds, - }); - this.updateLog( - depIds, - `开始${actionText}依赖 ${depNames},开始时间 ${new Date( - startTime, - ).toLocaleString()}\n`, - ); - cp.stdout.on('data', (data) => { + return new Promise((resolve) => { + if (dependencies.length === 0) { + resolve(null); + return; + } + const depNames = dependencies.map((x) => x.name).join(' '); + const depRunCommand = ( + isInstall + ? InstallDependenceCommandTypes + : unInstallDependenceCommandTypes + )[dependencies[0].type as any]; + const actionText = isInstall ? '安装' : '删除'; + const depIds = dependencies.map((x) => x._id) as string[]; + const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' }); + const startTime = Date.now(); this.sockService.sendMessage({ type: 'installDependence', - message: data.toString(), - references: depIds, - }); - this.updateLog(depIds, data.toString()); - }); - - cp.stderr.on('data', (data) => { - this.sockService.sendMessage({ - type: 'installDependence', - message: data.toString(), - references: depIds, - }); - this.updateLog(depIds, data.toString()); - }); - - cp.on('error', (err) => { - this.sockService.sendMessage({ - type: 'installDependence', - message: JSON.stringify(err), - references: depIds, - }); - this.updateLog(depIds, JSON.stringify(err)); - }); - - cp.on('close', (code) => { - const endTime = Date.now(); - const isSucceed = code === 0; - const resultText = isSucceed ? '成功' : '失败'; - - this.sockService.sendMessage({ - type: 'installDependence', - message: `依赖${actionText}${resultText},结束时间 ${new Date( - endTime, - ).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`, + message: `开始${actionText}依赖 ${depNames},开始时间 ${new Date( + startTime, + ).toLocaleString()}`, references: depIds, }); this.updateLog( depIds, - `依赖${actionText}${resultText},结束时间 ${new Date( - endTime, - ).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`, + `开始${actionText}依赖 ${depNames},开始时间 ${new Date( + startTime, + ).toLocaleString()}\n`, ); + cp.stdout.on('data', (data) => { + this.sockService.sendMessage({ + type: 'installDependence', + message: data.toString(), + references: depIds, + }); + this.updateLog(depIds, data.toString()); + }); - let status = null; - if (isSucceed) { - status = isInstall - ? DependenceStatus.installed - : DependenceStatus.removed; - } else { - status = isInstall - ? DependenceStatus.installFailed - : DependenceStatus.removeFailed; - } - this.dependenceDb.update( - { _id: { $in: depIds } }, - { - $set: { status }, - $unset: { pid: true }, - }, - { multi: true }, - ); + cp.stderr.on('data', (data) => { + this.sockService.sendMessage({ + type: 'installDependence', + message: data.toString(), + references: depIds, + }); + this.updateLog(depIds, data.toString()); + }); - // 如果删除依赖成功,3秒后删除数据库记录 - if (isSucceed && !isInstall) { - setTimeout(() => { - this.removeDb(depIds); - }, 5000); - } + cp.on('error', (err) => { + this.sockService.sendMessage({ + type: 'installDependence', + message: JSON.stringify(err), + references: depIds, + }); + this.updateLog(depIds, JSON.stringify(err)); + resolve(null); + }); + + cp.on('close', (code) => { + const endTime = Date.now(); + const isSucceed = code === 0; + const resultText = isSucceed ? '成功' : '失败'; + + this.sockService.sendMessage({ + type: 'installDependence', + message: `依赖${actionText}${resultText},结束时间 ${new Date( + endTime, + ).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`, + references: depIds, + }); + this.updateLog( + depIds, + `依赖${actionText}${resultText},结束时间 ${new Date( + endTime, + ).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`, + ); + + let status = null; + if (isSucceed) { + status = isInstall + ? DependenceStatus.installed + : DependenceStatus.removed; + } else { + status = isInstall + ? DependenceStatus.installFailed + : DependenceStatus.removeFailed; + } + this.dependenceDb.update( + { _id: { $in: depIds } }, + { + $set: { status }, + $unset: { pid: true }, + }, + { multi: true }, + ); + + // 如果删除依赖成功,3秒后删除数据库记录 + if (isSucceed && !isInstall) { + setTimeout(() => { + this.removeDb(depIds); + }, 5000); + } + + resolve(null); + }); }); } }