新增 终止异步任务功能

This commit is contained in:
Suwings 2022-03-16 09:15:34 +08:00
parent c7a8d4e367
commit 4b48053ae7
5 changed files with 51 additions and 9 deletions

View File

@ -22,4 +22,5 @@
export default class InstanceCommand {
constructor(public info?: string) {}
async exec(instance: any): Promise<any> {}
async stop(instance: any) {}
}

View File

@ -26,12 +26,21 @@ import InstanceCommand from "../base/command";
import { commandStringToArray } from "../base/command_parser";
import iconv from "iconv-lite";
export default class GeneralUpdateCommand extends InstanceCommand {
private pid: number = null;
constructor() {
super("GeneralUpdateCommand");
}
private stoped(instance: Instance) {
instance.asynchronousTask = null;
instance.setLock(false);
instance.status(Instance.STATUS_STOP);
}
async exec(instance: Instance) {
if (instance.status() !== Instance.STATUS_STOP) return instance.failure(new Error("实例状态不正确,无法执行更新任务,必须停止实例"));
if (instance.asynchronousTask !== null) return instance.failure(new Error("实例状态不正确,有其他任务正在运行中"));
try {
instance.setLock(true);
const updateCommand = instance.config.updateCommand;
@ -54,10 +63,15 @@ export default class GeneralUpdateCommand extends InstanceCommand {
windowsHide: true
});
if (!process || !process.pid) {
instance.setLock(false);
this.stoped(instance);
return instance.println("错误", "更新失败,更新命令启动失败,请联系管理员");
}
//pid 保存
this.pid = process.pid;
// 设置实例正在运行的异步任务
instance.asynchronousTask = this;
instance.status(Instance.STATUS_BUSY);
process.stdout.on("data", (text) => {
@ -67,8 +81,7 @@ export default class GeneralUpdateCommand extends InstanceCommand {
instance.println("异常", iconv.decode(text, instance.config.oe));
});
process.on("exit", (code) => {
instance.setLock(false);
instance.status(Instance.STATUS_STOP);
this.stoped(instance);
if (code === 0) {
instance.println("更新", "更新成功!");
} else {
@ -76,8 +89,11 @@ export default class GeneralUpdateCommand extends InstanceCommand {
}
});
} catch {
instance.setLock(false);
instance.status(Instance.STATUS_STOP);
this.stoped(instance);
}
}
async stop(instance: Instance): Promise<void> {
logger.info(`用户请求终止实例 ${instance.instanceUuid} 的 update 异步任务`);
}
}

View File

@ -22,7 +22,7 @@
import { EventEmitter } from "events";
import iconv from "iconv-lite";
import path from "path";
import { IExecutable } from "./preset";
import InstanceCommand from "../commands/base/command";
import InstanceConfig from "./Instance_config";
import StorageSubsystem from "../../common/system_storage";
@ -64,6 +64,8 @@ export default class Instance extends EventEmitter {
public lock: boolean;
public startCount: number;
public startTimestamp: number = 0;
// 正在进行的异步任务
public asynchronousTask: IExecutable = null;
// 生命周期任务,定时任务管理器
public readonly lifeCycleTaskManager = new LifeCycleTaskManager(this);

View File

@ -19,8 +19,9 @@
https://mcsmanager.com/ 阅读用户协议,申请闭源开发授权等。
*/
interface IExecutable {
export interface IExecutable {
exec: (a: any, b?: any) => Promise<any>;
stop?: (a: any) => Promise<void>;
}
export class PresetCommandManager {

View File

@ -285,13 +285,35 @@ routerApp.on("instance/asynchronous", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const taskName = data.taskName;
const parameter = data.parameter;
if (taskName === "update") {
const instance = InstanceSubsystem.getInstance(instanceUuid);
instance.execPreset("update", parameter).then(() => {});
logger.info(`会话 ${ctx.socket.id} 要求实例 ${instance.instanceUuid} 执行异步 ${taskName} 异步任务`);
if (taskName === "update") {
instance
.execPreset("update", parameter)
.then(() => {})
.catch((err) => {
logger.error(`实例 ${instance.instanceUuid} ${taskName} 异步任务执行异常: ${err}`);
});
}
protocol.msg(ctx, "instance/asynchronous", true);
});
// 终止执行复杂异步任务
routerApp.on("instance/stop_asynchronous", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const instance = InstanceSubsystem.getInstance(instanceUuid);
const task = instance.asynchronousTask;
if (task && task.stop) {
task
.stop(instance)
.then(() => {})
.catch((err) => {});
} else {
return protocol.error(ctx, "instance/stop_asynchronous", "无任务异步任务正在运行");
}
protocol.msg(ctx, "instance/stop_asynchronous", true);
});
// 向应用实例发送数据流
routerApp.on("instance/stdin", (ctx, data) => {
// 本路由采用兼容性低且直接原始的方式来进行写数据