fixed:下载及安装插件时突然断网导致界面卡住的问题

Change-Id: I974ef3a9a6c95c31df18bd5f7c3c94b14d957e04
This commit is contained in:
dinglili 2024-08-18 20:22:12 +08:00 committed by wangpenglong
parent f9b1e976d7
commit 293bb1c5f6
2 changed files with 85 additions and 22 deletions

View File

@ -83,7 +83,7 @@ class deployWindow {
extName: msg.extName extName: msg.extName
}; };
this.extInstallState.set(msg.extName, 2); this.extInstallState.set(msg.extName, 2);
console.log("render send kylinide.installWizard.msg.process"); console.log("render send kylinide.installWizard.msg.process,installExt");
ipcRenderer.send("kylinide.installWizard.msg.process", installMsg); ipcRenderer.send("kylinide.installWizard.msg.process", installMsg);
} }
else if (msg.type == "extInstalled") { else if (msg.type == "extInstalled") {
@ -151,7 +151,7 @@ class deployWindow {
} }
else if (msg.type === "extDownloadInit") { else if (msg.type === "extDownloadInit") {
console.log("receive: kylinide.installWizard.msg:extDownloadInit"); console.log("receive: kylinide.installWizard.msg:extDownloadInit");
await ipcRenderer.invoke('kylinide.installWizard.downloadExt', { ipcRenderer.send('kylinide.installWizard.downloadExt', {
extAddressPath: this.extAddressPath, extAddressPath: this.extAddressPath,
configList: this.configList configList: this.configList
}); });

View File

@ -240,6 +240,7 @@ export class DeployMainService implements IDeployMainService {
} }
this.logger.debug("安装 ext installCommand", installCommand); this.logger.debug("安装 ext installCommand", installCommand);
if (this.installQueue?.length === 0) { if (this.installQueue?.length === 0) {
this.logger.info("将命令放入installQueue中", installCommand);
this.installQueue.push({ installCommand, msg }); this.installQueue.push({ installCommand, msg });
if (!this.cancelFlag) { if (!this.cancelFlag) {
await this.executeNextInstall(); await this.executeNextInstall();
@ -247,8 +248,11 @@ export class DeployMainService implements IDeployMainService {
} }
else { else {
if (!this.cancelFlag) if (!this.cancelFlag) {
this.logger.info("将命令放入installQueue中", installCommand);
this.installQueue?.push({ installCommand, msg }); this.installQueue?.push({ installCommand, msg });
}
} }
} catch (error) { } catch (error) {
this.logger.error(`安装 ext 执行出错 ${installCommand}: ${error.message}`); this.logger.error(`安装 ext 执行出错 ${installCommand}: ${error.message}`);
@ -903,8 +907,9 @@ export class DeployMainService implements IDeployMainService {
if (this.DeployWindow) if (this.DeployWindow)
this.DeployWindow.webContents.send('kylinide.installWizard.msg', startDownloadMsg); this.DeployWindow.webContents.send('kylinide.installWizard.msg', startDownloadMsg);
if (!this.cancelFlag) { if (!this.cancelFlag) {
//检查缓存目录是否已经存在插件
this.logger.info(`开始下载扩展 ${val}${this.extDownloadPath + filename}${downloadUrlAddr}`); this.logger.info(`开始下载扩展 ${val}${this.extDownloadPath + filename}${downloadUrlAddr}`);
this.download_File(downloadUrlAddr, this.extDownloadPath + filename, this.controller).then((result) => { this.download_VSIX(downloadUrlAddr, this.extDownloadPath + filename, this.controller).then((result) => {
const msg = { const msg = {
type: 'downloadExtDone', type: 'downloadExtDone',
fileName: filename, fileName: filename,
@ -914,21 +919,9 @@ export class DeployMainService implements IDeployMainService {
}; };
if (result === 0) { if (result === 0) {
if (this.DeployWindow) this.DeployWindow.webContents.send('kylinide.installWizard.msg', msg); if (this.DeployWindow) this.DeployWindow.webContents.send('kylinide.installWizard.msg', msg);
} else {
this.println(`Download ${val} failed0: `);
this.logger.error(`下载扩展 ${val} 失败`);
const msg = {
type: 'downloadExtFail',
fileName: filename,
extName: val,
extMap: this.extMap,
extTotal: Object.keys(this.extMap).length,
};
if (this.DeployWindow) this.DeployWindow.webContents.send('kylinide.installWizard.msg', msg);
} }
}).catch((error) => { }).catch((error) => {
this.logger.error(`下载扩展 ${val} 异常: ${error}`); this.logger.error(`下载扩展 ${val} 异常: ${error}`);
this.println(`Download ${val} failed1: ${error}`);
const msg = { const msg = {
type: 'downloadExtFail', type: 'downloadExtFail',
fileName: filename ? filename : val, fileName: filename ? filename : val,
@ -940,9 +933,10 @@ export class DeployMainService implements IDeployMainService {
if (this.DeployWindow) this.DeployWindow.webContents.send('kylinide.installWizard.msg', msg); if (this.DeployWindow) this.DeployWindow.webContents.send('kylinide.installWizard.msg', msg);
}); });
} }
} catch (error) { } catch (error) {
this.println(`Download ${val} failed2: ${error}`);
this.logger.error(`下载 ${val} 异常: ${error}`); this.logger.error(`下载 ${val} 异常: ${error}`);
const msg = { const msg = {
type: 'downloadExtFail', type: 'downloadExtFail',
@ -986,6 +980,7 @@ export class DeployMainService implements IDeployMainService {
validatedIpcMain.removeListener('kylinide.installWizard.removeFileLister', this.listenerRemoveFileLister); validatedIpcMain.removeListener('kylinide.installWizard.removeFileLister', this.listenerRemoveFileLister);
validatedIpcMain.removeListener('kylinide.installWizard.init', this.listenerWriteSelectJson); validatedIpcMain.removeListener('kylinide.installWizard.init', this.listenerWriteSelectJson);
validatedIpcMain.removeListener('kylinide.installWizard.reloadwindow', this.listenerReloadWindow); validatedIpcMain.removeListener('kylinide.installWizard.reloadwindow', this.listenerReloadWindow);
validatedIpcMain.removeListener('kylinide.installWizard.downloadExt', this.handleDownExten);
} }
private registerListeners(): void { private registerListeners(): void {
this.logger.info("注册监听器"); this.logger.info("注册监听器");
@ -1006,7 +1001,7 @@ export class DeployMainService implements IDeployMainService {
validatedIpcMain.handle('kylinide.installWizard.init.httpVerify', this.handleHttpVerify); validatedIpcMain.handle('kylinide.installWizard.init.httpVerify', this.handleHttpVerify);
validatedIpcMain.handle('kylinide.installWizard.msg.deplist', this.handleDepList); validatedIpcMain.handle('kylinide.installWizard.msg.deplist', this.handleDepList);
validatedIpcMain.handle('kylinide.installWizard.checkInstall', this.handleCheckInstall); validatedIpcMain.handle('kylinide.installWizard.checkInstall', this.handleCheckInstall);
validatedIpcMain.handle('kylinide.installWizard.downloadExt', this.handleDownExten); validatedIpcMain.on('kylinide.installWizard.downloadExt', this.handleDownExten);
} }
//#endregion //#endregion
@ -1080,7 +1075,7 @@ export class DeployMainService implements IDeployMainService {
const { installCommand, msg } = this.installQueue[0]; const { installCommand, msg } = this.installQueue[0];
try { try {
const extlogFile = this.installConfig + '/log/extInstall.1.log'; const extlogFile = this.installConfig + '/log/extInstall.1.log';
this.logger.info(`开始执行${installCommand}`);
let ret: { stdout: string, stderr: string } = await this.spawnCommand(installCommand) as { stdout: string; stderr: string; }; let ret: { stdout: string, stderr: string } = await this.spawnCommand(installCommand) as { stdout: string; stderr: string; };
if (ret.stdout) { if (ret.stdout) {
fs.appendFileSync(extlogFile, ret.stdout); fs.appendFileSync(extlogFile, ret.stdout);
@ -1126,7 +1121,7 @@ export class DeployMainService implements IDeployMainService {
} }
this.installQueue.shift(); // 执行完成后,将当前消息从队列中移除 this.installQueue.shift(); // 执行完成后,将当前消息从队列中移除
if (!this.cancelFlag) if (!this.cancelFlag && this.installQueue.length > 0)
await this.executeNextInstall(); // 继续执行下一个消息 await this.executeNextInstall(); // 继续执行下一个消息
else { this.installQueue.splice(0) } else { this.installQueue.splice(0) }
} }
@ -1147,6 +1142,7 @@ export class DeployMainService implements IDeployMainService {
}); });
child.on('close', (code) => { child.on('close', (code) => {
clearTimeout(timer);
this.controller.signal.removeEventListener('abort', cancelTask); this.controller.signal.removeEventListener('abort', cancelTask);
if (code === 0) { if (code === 0) {
resolve({ stdout, stderr }); resolve({ stdout, stderr });
@ -1154,9 +1150,18 @@ export class DeployMainService implements IDeployMainService {
reject(new Error(`Command failed with exit code ${code} `)); reject(new Error(`Command failed with exit code ${code} `));
} }
}); });
const cancelTask = () => { const timer = setTimeout(() => {
if (child.pid) reject(new Error('命令执行超时'));
if (child && child.pid) {
execSync(`kill -9 -${child.pid}`); execSync(`kill -9 -${child.pid}`);
}
}, 1200000);
const cancelTask = () => {
if (child.pid) {
reject(new Error('取消命令'))
execSync(`kill -9 -${child.pid}`);
}
} }
this.controller.signal.addEventListener('abort', cancelTask); this.controller.signal.addEventListener('abort', cancelTask);
}); });
@ -1470,6 +1475,14 @@ export class DeployMainService implements IDeployMainService {
resolve(0); resolve(0);
}); });
response.data.on('error', () => {
this.logger.error("文件下载失败:" + dst, "response data on error");
if (fs.existsSync(dst)) {
fs.unlinkSync(dst);
}
reject(-1);
});
writer.on('error', (err) => { writer.on('error', (err) => {
console.error('写入文件时发生错误:', err); console.error('写入文件时发生错误:', err);
if (fs.existsSync(dst)) { if (fs.existsSync(dst)) {
@ -1492,6 +1505,56 @@ export class DeployMainService implements IDeployMainService {
} }
} }
private async download_VSIX(url_git: string, dst: string, controller?: AbortController) {
return new Promise(async (resolve, reject) => {
try {
const directoryPath = path.dirname(dst);
// 判断目录是否存在
if (!fs.existsSync(directoryPath)) {
// 创建目录
fs.mkdirSync(directoryPath, { recursive: true });
}
const response = await axios.get(url_git, { responseType: 'stream', timeout: 10000, signal: this.controller?.signal });
const writer = fs.createWriteStream(dst);
response.data.pipe(writer);
writer.on('open', () => {
this.logger.info("文件开始写入:" + dst);
});
writer.on('finish', () => {
this.logger.info("文件下载成功:" + dst);
resolve(0);
});
response.data.on('error', () => {
this.logger.error("文件下载失败:" + dst, "response data on error");
if (fs.existsSync(dst)) {
fs.unlinkSync(dst);
}
reject(-1);
});
writer.on('error', (err) => {
this.logger.error('文件下载失败,写入文件时发生错误:', dst, err);
if (fs.existsSync(dst)) {
fs.unlinkSync(dst);
}
reject(-1);
});
} catch (error) {
this.logger.error("文件下载失败:" + dst);
if (axios.isCancel(error)) {
this.logger.error('文件下载请求已取消', dst);
}
else if (error.code === 'ECONNABORTED') {
this.logger.error("文件下载请求超时", dst);
} else {
this.logger.error('文件下载请求发生错误', dst, error);
}
reject(-1);
}
})
}
private async localConfigVerify(configDir: string, IDEVersion: string) { private async localConfigVerify(configDir: string, IDEVersion: string) {
try { try {
var dst = path.join(configDir, "./g_index.json"); var dst = path.join(configDir, "./g_index.json");