mirror of https://github.com/certd/certd
fix: 修复在相同的cron时偶尔无法触发定时任务的bug
parent
1cf8d4e5e7
commit
680941af11
|
@ -3,9 +3,8 @@ import { logger } from "../utils/index.js";
|
|||
|
||||
const SecreteKey =
|
||||
"LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQXY3TGtMaUp1dGM0NzhTU3RaTExjajVGZXh1YjJwR2NLMGxwa0hwVnlZWjhMY29rRFhuUlAKUGQ5UlJSTVRTaGJsbFl2Mzd4QUhOV1ZIQ0ZsWHkrQklVU001bUlBU1NDQTV0azlJNmpZZ2F4bEFDQm1BY0lGMwozKzBjeGZIYVkrVW9YdVluMkZ6YUt2Ym5GdFZIZ0lkMDg4a3d4clZTZzlCT3BDRVZIR1pxR2I5TWN5MXVHVXhUClFTVENCbmpoTWZlZ0p6cXVPYWVOY0ZPSE5tbmtWRWpLTythbTBPeEhNS1lyS3ZnQnVEbzdoVnFENlBFMUd6V3AKZHdwZUV4QXZDSVJxL2pWTkdRK3FtMkRWOVNJZ3U5bmF4MktmSUtFeU50dUFFS1VpekdqL0VmRFhDM1cxMExhegpKaGNYNGw1SUFZU1o3L3JWVmpGbExWSVl0WDU1T054L1Z3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K";
|
||||
|
||||
const appKey = "z4nXOeTeSnnpUpnmsV";
|
||||
export type LicenseVerifyReq = {
|
||||
appKey: string;
|
||||
subjectId: string;
|
||||
license: string;
|
||||
};
|
||||
|
@ -33,13 +32,10 @@ class LicenseVerifier {
|
|||
licenseReq?: LicenseVerifyReq = undefined;
|
||||
async reVerify(req: LicenseVerifyReq) {
|
||||
this.checked = false;
|
||||
//@ts-ignore
|
||||
// globalThis._certd_license_.isPlus = false;
|
||||
return await this.verify(req);
|
||||
}
|
||||
|
||||
setPlus(value: boolean) {
|
||||
//@ts-ignore
|
||||
holder.isPlus = value;
|
||||
return value;
|
||||
}
|
||||
|
@ -60,7 +56,7 @@ class LicenseVerifier {
|
|||
logger.warn("授权已过期");
|
||||
return this.setPlus(false);
|
||||
}
|
||||
const content = `${this.licenseReq.appKey},${this.licenseReq.subjectId},${json.code},${json.secret},${json.activeTime},${json.duration},${json.expireTime},${json.version}`;
|
||||
const content = `${appKey},${this.licenseReq.subjectId},${json.code},${json.secret},${json.activeTime},${json.duration},${json.expireTime},${json.version}`;
|
||||
const publicKey = Buffer.from(SecreteKey, "base64").toString();
|
||||
const res = this.verifySignature(content, json.signature, publicKey);
|
||||
this.checked = true;
|
||||
|
|
|
@ -336,6 +336,21 @@ function install(app: App, options: any = {}) {
|
|||
return columnProps;
|
||||
}
|
||||
});
|
||||
|
||||
registerMergeColumnPlugin({
|
||||
name: "resize-column-plugin",
|
||||
order: 2,
|
||||
handle: (columnProps: ColumnCompositionProps) => {
|
||||
if (!columnProps.column) {
|
||||
columnProps.column = {};
|
||||
}
|
||||
columnProps.column.resizable = true;
|
||||
if (!columnProps.column.width) {
|
||||
columnProps.column.width = 100;
|
||||
}
|
||||
return columnProps;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -6,12 +6,10 @@ export function useReference(form: any) {
|
|||
return;
|
||||
}
|
||||
for (const reference of form.reference) {
|
||||
debugger;
|
||||
_.set(
|
||||
form,
|
||||
reference.dest,
|
||||
compute<any>((scope) => {
|
||||
debugger;
|
||||
return _.get(scope, reference.src);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"bcryptjs": "^2.4.3",
|
||||
"better-sqlite3": "^11.1.2",
|
||||
"cache-manager": "^3.6.3",
|
||||
"cron-parser": "^4.9.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"glob": "^10.4.5",
|
||||
"https-proxy-agent": "^7.0.4",
|
||||
|
@ -56,7 +57,6 @@
|
|||
"md5": "^2.3.0",
|
||||
"mwtsc": "^1.4.0",
|
||||
"nanoid": "^4.0.0",
|
||||
"node-cron": "^3.0.2",
|
||||
"nodemailer": "^6.9.3",
|
||||
"pg": "^8.12.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
|
|
|
@ -35,7 +35,11 @@ export class AutoInitSite {
|
|||
|
||||
// 授权许可
|
||||
const licenseInfo: SysLicenseInfo = await this.sysSettingsService.getSetting(SysLicenseInfo);
|
||||
await verify(licenseInfo.license);
|
||||
const req = {
|
||||
subjectId: installInfo.siteId,
|
||||
license: licenseInfo.license,
|
||||
};
|
||||
await verify(req);
|
||||
|
||||
logger.info('初始化站点完成');
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.info('定时器数量:', this.cron.getListSize());
|
||||
logger.info('定时器数量:', this.cron.getTaskSize());
|
||||
}
|
||||
|
||||
async registerTriggers(pipeline?: Pipeline, immediateTriggerOnce = false) {
|
||||
|
@ -193,7 +193,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
}
|
||||
},
|
||||
});
|
||||
logger.info('当前定时器数量:', this.cron.getListSize());
|
||||
logger.info('当前定时器数量:', this.cron.getTaskSize());
|
||||
}
|
||||
|
||||
async run(id: number, triggerId: string) {
|
||||
|
@ -212,6 +212,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
const onChanged = async (history: RunHistory) => {
|
||||
//保存执行历史
|
||||
try {
|
||||
logger.info('保存执行历史:', history.id);
|
||||
await this.saveHistory(history);
|
||||
} catch (e) {
|
||||
const pipelineEntity = new PipelineEntity();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import cron from 'node-cron';
|
||||
export type CronTask = {
|
||||
import parser from 'cron-parser';
|
||||
import { ILogger } from '@certd/pipeline';
|
||||
|
||||
export type CronTaskReq = {
|
||||
/**
|
||||
* 为空则为单次执行
|
||||
*/
|
||||
|
@ -7,39 +9,90 @@ export type CronTask = {
|
|||
job: () => Promise<void>;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export class CronTask {
|
||||
logger: ILogger;
|
||||
cron: string;
|
||||
job: () => Promise<void>;
|
||||
name: string;
|
||||
stoped = false;
|
||||
|
||||
timeoutId: any;
|
||||
|
||||
constructor(req: CronTaskReq, logger: ILogger) {
|
||||
this.cron = req.cron;
|
||||
this.job = req.job;
|
||||
this.name = req.name;
|
||||
this.logger = logger;
|
||||
this.start();
|
||||
}
|
||||
|
||||
start() {
|
||||
if (!this.cron) {
|
||||
return;
|
||||
}
|
||||
if (this.stoped) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.stoped = true;
|
||||
clearTimeout(this.timeoutId);
|
||||
}
|
||||
}
|
||||
export class Cron {
|
||||
logger;
|
||||
logger: ILogger;
|
||||
immediateTriggerOnce: boolean;
|
||||
constructor(opts) {
|
||||
|
||||
bucket: Record<string, CronTask> = {};
|
||||
|
||||
constructor(opts: any) {
|
||||
this.logger = opts.logger;
|
||||
this.immediateTriggerOnce = opts.immediateTriggerOnce;
|
||||
}
|
||||
|
||||
register(task: CronTask) {
|
||||
if (!task.cron) {
|
||||
this.logger.info(`[cron] register once : [${task.name}]`);
|
||||
task.job();
|
||||
register(req: CronTaskReq) {
|
||||
if (!req.cron) {
|
||||
this.logger.info(`[cron] register once : [${req.name}]`);
|
||||
req.job().catch(e => {
|
||||
this.logger.error(`job execute error : [${req.name}]`, e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.logger.info(`[cron] register cron : [${task.name}] ,${task.cron}`);
|
||||
cron.schedule(task.cron, task.job, {
|
||||
name: task.name,
|
||||
});
|
||||
this.logger.info('当前定时任务数量:', this.getListSize());
|
||||
this.logger.info(`[cron] register cron : [${req.name}] ,${req.cron}`);
|
||||
|
||||
const task = new CronTask(req, this.logger);
|
||||
this.bucket[task.name] = task;
|
||||
this.logger.info('当前定时任务数量:', this.getTaskSize());
|
||||
}
|
||||
|
||||
remove(taskName: string) {
|
||||
this.logger.info(`[cron] remove : [${taskName}]`);
|
||||
const tasks = cron.getTasks() as Map<any, any>;
|
||||
const node = tasks.get(taskName);
|
||||
if (node) {
|
||||
node.stop();
|
||||
tasks.delete(taskName);
|
||||
const task = this.bucket[taskName];
|
||||
if (task) {
|
||||
task.stop();
|
||||
delete this.bucket[taskName];
|
||||
}
|
||||
}
|
||||
|
||||
getListSize() {
|
||||
const tasks = cron.getTasks();
|
||||
return tasks.size;
|
||||
getTaskSize() {
|
||||
const tasks = Object.keys(this.bucket);
|
||||
return tasks.length;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,5 +32,5 @@ export class SysLicenseInfo extends BaseSettings {
|
|||
static __title__ = '授权许可信息';
|
||||
static __key__ = 'sys.license';
|
||||
static __access__ = 'private';
|
||||
license: string;
|
||||
license?: string;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue