diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx index 6d467fdbd..38d538e74 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx @@ -187,6 +187,9 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp title: "ID", key: "id", type: "number", + search: { + show: true + }, column: { width: 50 }, @@ -233,6 +236,31 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp } } }, + content: { + title: "定时任务数量", + type: "number", + column: { + cellRender({ value }) { + if (value && value.triggers) { + return value.triggers?.length > 0 ? value.triggers.length : "-"; + } + return "-"; + } + }, + valueBuilder({ row }) { + if (row.content) { + row.content = JSON.parse(row.content); + } + }, + valueResolve({ row }) { + if (row.content) { + row.content = JSON.stringify(row.content); + } + }, + form: { + show: false + } + }, lastVars: { title: "到期剩余", type: "number", diff --git a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts index c640fc33e..568436c0f 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts @@ -88,15 +88,16 @@ export class PipelineService extends BaseService { } async update(bean: PipelineEntity) { - await this.clearTriggers(bean.id); + //更新非trigger部分 await super.update(bean); - await this.registerTriggerById(bean.id); } async save(bean: PipelineEntity) { await this.clearTriggers(bean.id); - const pipeline = JSON.parse(bean.content); - bean.title = pipeline.title; + if (bean.content) { + const pipeline = JSON.parse(bean.content); + bean.title = pipeline.title; + } await this.addOrUpdate(bean); await this.registerTriggerById(bean.id); } diff --git a/packages/ui/certd-server/src/modules/plugin/cron/configuration.ts b/packages/ui/certd-server/src/modules/plugin/cron/configuration.ts index 11ad2ea06..a1043f4f7 100644 --- a/packages/ui/certd-server/src/modules/plugin/cron/configuration.ts +++ b/packages/ui/certd-server/src/modules/plugin/cron/configuration.ts @@ -22,6 +22,7 @@ export class CronConfiguration { ...this.config, }); container.registerObject('cron', this.cron); + this.cron.start(); this.logger.info('cron started'); } } diff --git a/packages/ui/certd-server/src/modules/plugin/cron/cron.ts b/packages/ui/certd-server/src/modules/plugin/cron/cron.ts index 76804a785..8a19cfe38 100644 --- a/packages/ui/certd-server/src/modules/plugin/cron/cron.ts +++ b/packages/ui/certd-server/src/modules/plugin/cron/cron.ts @@ -17,56 +17,64 @@ export class CronTask { name: string; stoped = false; - timeoutId: any; + nextTime: any; constructor(req: CronTaskReq, logger: ILogger) { this.cron = req.cron; this.job = req.job; this.name = req.name; this.logger = logger; - this.start(); } - start() { + genNextTime() { if (!this.cron) { - return; + return null; } if (this.stoped) { - return; + return null; } const interval = parser.parseExpression(this.cron); const next = interval.next().getTime(); - const now = Date.now(); - const delay = next - now; - this.timeoutId = setTimeout(async () => { - try { - if (this.stoped) { - return; - } - await this.job(); - } catch (e) { - this.logger.error(`[cron] job error : [${this.name}]`, e); - } - this.start(); - }, delay); + this.logger.info(`[cron] [${this.name}], cron:${this.cron}, next run :${new Date(next).toLocaleString()}`); + this.nextTime = next; + return next; } stop() { this.stoped = true; - clearTimeout(this.timeoutId); } } export class Cron { logger: ILogger; immediateTriggerOnce: boolean; - bucket: Record = {}; - + queue: CronTask[] = []; constructor(opts: any) { this.logger = opts.logger; this.immediateTriggerOnce = opts.immediateTriggerOnce; } + start() { + this.logger.info('[cron] start'); + this.queue.forEach(task => { + task.genNextTime(); + }); + + setInterval(() => { + const now = new Date().getTime(); + for (const task of this.queue) { + if (task.nextTime <= now) { + task.job().catch(e => { + this.logger.error(`job execute error : [${task.name}]`, e); + }); + task.genNextTime(); + } else { + break; + } + } + }, 1000 * 60); + } + register(req: CronTaskReq) { if (!req.cron) { this.logger.info(`[cron] register once : [${req.name}]`); @@ -78,21 +86,26 @@ export class Cron { this.logger.info(`[cron] register cron : [${req.name}] ,${req.cron}`); const task = new CronTask(req, this.logger); - this.bucket[task.name] = task; + task.genNextTime(); + this.queue.push(task); + + // sort by nextTime + this.queue.sort((a, b) => a.nextTime - b.nextTime); + this.logger.info('当前定时任务数量:', this.getTaskSize()); } remove(taskName: string) { this.logger.info(`[cron] remove : [${taskName}]`); - const task = this.bucket[taskName]; - if (task) { - task.stop(); - delete this.bucket[taskName]; + const index = this.queue.findIndex(item => item.name === taskName); + if (index !== -1) { + this.queue[index].stop(); + this.queue.splice(index, 1); } } getTaskSize() { - const tasks = Object.keys(this.bucket); + const tasks = Object.keys(this.queue); return tasks.length; } } diff --git a/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts b/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts index 644c197b8..126648ced 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/lib/ssh.ts @@ -75,6 +75,10 @@ export class AsyncSsh2Client { } async exec(script: string) { + if (!script) { + this.logger.info('script 为空,取消执行'); + return; + } return new Promise((resolve, reject) => { this.logger.info(`执行命令:[${this.connConf.host}][exec]: ` + script); this.conn.exec(script, (err: Error, stream: any) => { @@ -97,6 +101,10 @@ export class AsyncSsh2Client { data += out; this.logger.info(`[${this.connConf.host}][info]: ` + out.trimEnd()); }) + .on('error', (err: any) => { + reject(err); + this.logger.error(err); + }) .stderr.on('data', (ret: Buffer) => { const err = this.convert(ret); data += err; diff --git a/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts b/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts index 7b85cc9a2..1b9b7361e 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/plugin/host-shell-execute/index.ts @@ -30,6 +30,7 @@ export class HostShellExecutePlugin extends AbstractTaskPlugin { name: 'a-textarea', vModel: 'value', }, + required: true, }) script!: string;