refactor: history

pull/9/head^2
xiaojunnuo 2022-10-30 01:13:08 +08:00
parent dcdb25d92d
commit 909b75eb40
5 changed files with 67 additions and 57 deletions

View File

@ -12,13 +12,13 @@
}, },
"dependencies": { "dependencies": {
"@certd/acme-client": "^0.3.0", "@certd/acme-client": "^0.3.0",
"@fast-crud/fast-crud": "^1.5.0",
"@types/lodash": "^4.14.186",
"dayjs": "^1.11.6", "dayjs": "^1.11.6",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"node-forge": "^0.10.0" "node-forge": "^0.10.0"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.14.186",
"@fast-crud/fast-crud": "^1.5.0",
"vue-tsc": "^0.38.9", "vue-tsc": "^0.38.9",
"@alicloud/cs20151215": "^3.0.3", "@alicloud/cs20151215": "^3.0.3",
"@alicloud/openapi-client": "^0.4.0", "@alicloud/openapi-client": "^0.4.0",

View File

@ -1,6 +1,6 @@
import { ConcurrencyStrategy, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts"; import { ConcurrencyStrategy, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts";
import _ from "lodash"; import _ from "lodash";
import { HistoryStatus, RunHistory } from "./run-history"; import { RunHistory } from "./run-history";
import { pluginRegistry, TaskPlugin } from "../plugin"; import { pluginRegistry, TaskPlugin } from "../plugin";
import { IAccessService } from "../access/access-service"; import { IAccessService } from "../access/access-service";
import { ContextFactory, IContext } from "./context"; import { ContextFactory, IContext } from "./context";
@ -18,7 +18,7 @@ export class Executor {
pipelineContext: IContext; pipelineContext: IContext;
onChanged: (history: RunHistory) => void; onChanged: (history: RunHistory) => void;
constructor(options: { userId: any; pipeline: Pipeline; storage: IStorage; onChanged: (history: RunHistory) => void; accessService: IAccessService }) { constructor(options: { userId: any; pipeline: Pipeline; storage: IStorage; onChanged: (history: RunHistory) => void; accessService: IAccessService }) {
this.pipeline = options.pipeline; this.pipeline = _.cloneDeep(options.pipeline);
this.onChanged = options.onChanged; this.onChanged = options.onChanged;
this.accessService = options.accessService; this.accessService = options.accessService;
this.userId = options.userId; this.userId = options.userId;
@ -29,7 +29,7 @@ export class Executor {
async run(runtimeId: any = 0) { async run(runtimeId: any = 0) {
try { try {
this.runtime = new RunHistory(runtimeId); this.runtime = new RunHistory(runtimeId, this.pipeline);
this.logger.info(`pipeline.${this.pipeline.id} start`); this.logger.info(`pipeline.${this.pipeline.id} start`);
await this.runWithHistory(this.pipeline, "pipeline", async () => { await this.runWithHistory(this.pipeline, "pipeline", async () => {
await this.runStages(); await this.runStages();
@ -39,9 +39,9 @@ export class Executor {
} }
} }
async runWithHistory(runnable: Runnable, runnableType: string, run: (status: HistoryStatus) => Promise<void>) { async runWithHistory(runnable: Runnable, runnableType: string, run: () => Promise<void>) {
runnable.runnableType = runnableType; runnable.runnableType = runnableType;
const status = this.runtime.start(runnable); this.runtime.start(runnable);
await this.onChanged(this.runtime); await this.onChanged(this.runtime);
const contextKey = `status.${runnable.id}`; const contextKey = `status.${runnable.id}`;
@ -49,21 +49,22 @@ export class Executor {
//如果是成功后跳过策略 //如果是成功后跳过策略
const lastResult = await this.pipelineContext.get(contextKey); const lastResult = await this.pipelineContext.get(contextKey);
if (lastResult != null && lastResult === ResultType.success) { if (lastResult != null && lastResult === ResultType.success) {
this.runtime.log(status, "跳过"); this.runtime.skip(runnable);
await this.onChanged(this.runtime);
return ResultType.skip; return ResultType.skip;
} }
} }
try { try {
await run(status); await run();
this.runtime.success(runnable); this.runtime.success(runnable);
await this.onChanged(this.runtime);
await this.pipelineContext.set(contextKey, ResultType.success); await this.pipelineContext.set(contextKey, ResultType.success);
await this.onChanged(this.runtime);
return ResultType.success; return ResultType.success;
} catch (e: any) { } catch (e: any) {
this.logger.error(e); this.logger.error(e);
this.runtime.error(runnable, e); this.runtime.error(runnable, e);
await this.onChanged(this.runtime);
await this.pipelineContext.set(contextKey, ResultType.error); await this.pipelineContext.set(contextKey, ResultType.error);
await this.onChanged(this.runtime);
throw e; throw e;
} finally { } finally {
this.runtime.finally(runnable); this.runtime.finally(runnable);
@ -122,17 +123,17 @@ export class Executor {
const resList: ResultType[] = []; const resList: ResultType[] = [];
for (const step of task.steps) { for (const step of task.steps) {
step.runnableType = "step"; step.runnableType = "step";
const res: ResultType = await this.runWithHistory(step, "step", async (status) => { const res: ResultType = await this.runWithHistory(step, "step", async () => {
await this.runStep(step, status); await this.runStep(step);
}); });
resList.push(res); resList.push(res);
} }
return this.compositionResultType(resList); return this.compositionResultType(resList);
} }
private async runStep(step: Step, status: HistoryStatus) { private async runStep(step: Step) {
//执行任务 //执行任务
const taskPlugin: TaskPlugin = await this.getPlugin(step.type, status.logger); const taskPlugin: TaskPlugin = await this.getPlugin(step.type, this.runtime.loggers[step.id]);
// @ts-ignore // @ts-ignore
delete taskPlugin.define; delete taskPlugin.define;
const define = taskPlugin.getDefine(); const define = taskPlugin.getDefine();

View File

@ -1,74 +1,83 @@
import { Context, HistoryResult, Runnable } from "../d.ts"; import { Context, HistoryResult, Pipeline, Runnable } from "../d.ts";
import _ from "lodash"; import _ from "lodash";
import { buildLogger } from "../utils/util.log"; import { buildLogger } from "../utils/util.log";
import { Logger } from "log4js"; import { Logger } from "log4js";
export type HistoryStatus = { export type HistoryStatus = {
runnable: Runnable;
result: HistoryResult; result: HistoryResult;
logs: string[]; logs: string[];
logger: Logger;
}; };
export class RunHistory { export class RunHistory {
constructor(runtimeId: any) { id: string;
this.id = runtimeId;
}
id: any;
//运行时上下文变量 //运行时上下文变量
context: Context = {}; context: Context = {};
status: { pipeline: Pipeline;
[nodeId: string]: HistoryStatus; logs: {
[runnableId: string]: string[];
} = {}; } = {};
loggers: {
[runnableId: string]: Logger;
} = {};
constructor(runtimeId: any, pipeline: Pipeline) {
this.id = runtimeId;
this.pipeline = pipeline;
}
start(runnable: Runnable): HistoryStatus { start(runnable: Runnable): HistoryResult {
const now = new Date().getTime(); const now = new Date().getTime();
const status: HistoryStatus = { this.logs[runnable.id] = [];
runnable, this.loggers[runnable.id] = buildLogger((text) => {
result: { this.logs[runnable.id].push(text);
status: "start", });
startTime: now, const status: HistoryResult = {
}, status: "start",
logs: [], startTime: now,
logger: buildLogger((text) => { result: "start",
status.logs.push(text);
}),
}; };
this.status[runnable.id] = status; runnable.status = status;
this.log(status, `开始执行`); this.log(runnable, `开始执行`);
return status; return status;
} }
success(runnable: Runnable) { success(runnable: Runnable) {
const now = new Date().getTime(); const now = new Date().getTime();
const status = this.status[runnable.id]; const status = runnable.status;
_.merge(status, { _.merge(status, {
result: { status: "success",
status: "success", endTime: now,
endTime: now, result: "success",
},
}); });
this.log(status, `执行成功`); this.log(runnable, `执行成功`);
}
skip(runnable: Runnable) {
const now = new Date().getTime();
const status = runnable.status;
_.merge(status, {
status: "success",
endTime: now,
result: "skip",
});
this.log(runnable, `跳过`);
} }
error(runnable: Runnable, e: Error) { error(runnable: Runnable, e: Error) {
const now = new Date().getTime(); const now = new Date().getTime();
const status = this.status[runnable.id]; const status = runnable.status;
_.merge(status, { _.merge(status, {
result: { status: "error",
status: "error", endTime: now,
endTime: now, result: "error",
message: e.message, message: e.message,
},
}); });
this.log(status, `执行异常:${e.message}`); this.log(runnable, `执行异常:${e.message}`);
} }
log(status: HistoryStatus, text: string) { log(runnable: Runnable, text: string) {
const runnable = status.runnable; // @ts-ignore
status.logger.info(`[${runnable.title}]<id:${runnable.id}> [${runnable.runnableType}]`, text); this.loggers[runnable.id].info(`[${runnable.title}]<id:${runnable.id}> [${runnable.runnableType}]`, text);
} }
finally(runnable: Runnable) { finally(runnable: Runnable) {

View File

@ -57,14 +57,13 @@ export type Trigger = {
export type Runnable = { export type Runnable = {
id: string; id: string;
title: string; title: string;
status?: string;
lastTime?: number;
strategy?: RunnableStrategy; strategy?: RunnableStrategy;
runnableType?: string; // pipeline, stage, task , step runnableType?: string; // pipeline, stage, task , step
status?: HistoryResult;
}; };
export type Pipeline = Runnable & { export type Pipeline = Runnable & {
version: number; version?: number;
stages: Stage[]; stages: Stage[];
triggers: Trigger[]; triggers: Trigger[];
}; };

View File

@ -55,6 +55,7 @@ export type CertInfo = {
value: 20, value: 20,
component: { component: {
name: "a-input-number", name: "a-input-number",
vModel: "value",
}, },
helper: "到期前多少天后更新证书", helper: "到期前多少天后更新证书",
}, },