mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2025-12-13 02:02:48 +00:00
优化队列
This commit is contained in:
parent
e06968d20d
commit
b23f5a3375
@ -8,8 +8,8 @@
|
|||||||
"@cool-midway/core": "^4.0.15",
|
"@cool-midway/core": "^4.0.15",
|
||||||
"@cool-midway/es": "^4.0.2",
|
"@cool-midway/es": "^4.0.2",
|
||||||
"@cool-midway/oss": "^4.0.3",
|
"@cool-midway/oss": "^4.0.3",
|
||||||
"@cool-midway/queue": "^4.0.9",
|
"@cool-midway/queue": "/Users/mac/Documents/src/cool/admin/midway-core/queue/dist/",
|
||||||
"@cool-midway/redis": "^4.0.3",
|
"@cool-midway/redis": "^4.0.5",
|
||||||
"@cool-midway/socket": "^4.0.2",
|
"@cool-midway/socket": "^4.0.2",
|
||||||
"@cool-midway/wxpay": "^4.0.3",
|
"@cool-midway/wxpay": "^4.0.3",
|
||||||
"@midwayjs/bootstrap": "^2.14.0",
|
"@midwayjs/bootstrap": "^2.14.0",
|
||||||
|
|||||||
@ -11,8 +11,8 @@ export default (app: Application) => {
|
|||||||
// 模块描述
|
// 模块描述
|
||||||
description: '演示示例',
|
description: '演示示例',
|
||||||
// 中间件
|
// 中间件
|
||||||
middlewares: ['testMiddleware'],
|
middlewares: [],
|
||||||
// 全局中间件
|
// 全局中间件
|
||||||
globalMiddlewares: ['demoUserMiddleware'],
|
globalMiddlewares: [],
|
||||||
} as ModuleConfig;
|
} as ModuleConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Get, Inject, Post, Provide } from '@midwayjs/decorator';
|
import { Get, Inject, Post, Provide } from '@midwayjs/decorator';
|
||||||
import { CoolController, BaseController, CoolUrlTag } from '@cool-midway/core';
|
import { CoolController, BaseController, CoolUrlTag } from '@cool-midway/core';
|
||||||
import { IQueue } from '@cool-midway/queue';
|
|
||||||
import { DemoGoodsEntity } from '../../entity/goods';
|
import { DemoGoodsEntity } from '../../entity/goods';
|
||||||
import { DemoGoodsService } from '../../service/goods';
|
import { DemoGoodsService } from '../../service/goods';
|
||||||
|
import { DemoQueue } from '../../queue/demo';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品
|
* 商品
|
||||||
@ -30,7 +30,7 @@ export class DemoAppGoodsController extends BaseController {
|
|||||||
|
|
||||||
// 队列
|
// 队列
|
||||||
@Inject()
|
@Inject()
|
||||||
demoQueue: IQueue;
|
demoQueue: DemoQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求所有数据
|
* 请求所有数据
|
||||||
@ -47,12 +47,7 @@ export class DemoAppGoodsController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@Post('/queue', { summary: '发送队列数据' })
|
@Post('/queue', { summary: '发送队列数据' })
|
||||||
async queue() {
|
async queue() {
|
||||||
this.demoQueue.queue.add(
|
console.log(111, this.demoQueue);
|
||||||
{ a: 1 },
|
this.demoQueue.add({ a: 2 }, { delay: 2000 });
|
||||||
{
|
|
||||||
removeOnComplete: true,
|
|
||||||
removeOnFail: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import { App, Provide } from '@midwayjs/decorator';
|
import { App, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
|
||||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||||
import { ICoolQueue, Queue } from '@cool-midway/queue';
|
import { BaseCoolQueue, Queue } from '@cool-midway/queue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务
|
* 任务
|
||||||
*/
|
*/
|
||||||
@Queue()
|
@Queue()
|
||||||
|
@Scope(ScopeEnum.Singleton)
|
||||||
@Provide()
|
@Provide()
|
||||||
export abstract class DemoQueue implements ICoolQueue {
|
export class DemoQueue extends BaseCoolQueue {
|
||||||
@App()
|
@App()
|
||||||
app: IMidwayWebApplication;
|
app: IMidwayWebApplication;
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,30 @@
|
|||||||
import { App, Inject, Provide } from '@midwayjs/decorator';
|
import { App, Inject, Provide } from '@midwayjs/decorator';
|
||||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||||
import { ICoolQueue, Queue } from '@cool-midway/queue';
|
import { BaseCoolQueue, Queue } from '@cool-midway/queue';
|
||||||
import { TaskInfoService } from '../service/info';
|
import { TaskInfoService } from '../service/info';
|
||||||
|
import { Job } from 'bullmq';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务
|
* 任务
|
||||||
*/
|
*/
|
||||||
@Queue()
|
@Queue()
|
||||||
@Provide()
|
@Provide()
|
||||||
export abstract class TaskInfoQueue implements ICoolQueue {
|
export abstract class TaskInfoQueue extends BaseCoolQueue {
|
||||||
@App()
|
@App()
|
||||||
app: IMidwayWebApplication;
|
app: IMidwayWebApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
taskInfoService: TaskInfoService;
|
taskInfoService: TaskInfoService;
|
||||||
|
|
||||||
async data(job: any, done: any): Promise<void> {
|
async data(job: Job, done: any): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log('收到的数据', job.data);
|
|
||||||
const result = await this.taskInfoService.invokeService(job.data.service);
|
const result = await this.taskInfoService.invokeService(job.data.service);
|
||||||
this.taskInfoService.record(job.data, 1, JSON.stringify(result));
|
this.taskInfoService.record(job.data, 1, JSON.stringify(result));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.taskInfoService.record(job.data, 0, error);
|
this.taskInfoService.record(job.data, 0, error);
|
||||||
}
|
}
|
||||||
this.taskInfoService.updateNextRunTime(job.data.id);
|
this.taskInfoService.updateNextRunTime(job.data.id);
|
||||||
this.taskInfoService.updateStatus();
|
this.taskInfoService.updateStatus(job.data.id);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,11 @@ import { InjectEntityModel } from '@midwayjs/orm';
|
|||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { TaskInfoEntity } from '../entity/info';
|
import { TaskInfoEntity } from '../entity/info';
|
||||||
import { TaskLogEntity } from '../entity/log';
|
import { TaskLogEntity } from '../entity/log';
|
||||||
import { IQueue } from '@cool-midway/queue';
|
|
||||||
import { ILogger } from '@midwayjs/logger';
|
import { ILogger } from '@midwayjs/logger';
|
||||||
import { IMidwayWebApplication } from '@midwayjs/web';
|
import { IMidwayWebApplication } from '@midwayjs/web';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { Utils } from '../../../comm/utils';
|
import { Utils } from '../../../comm/utils';
|
||||||
|
import { TaskInfoQueue } from '../queue/task';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务
|
* 任务
|
||||||
@ -25,7 +25,7 @@ export class TaskInfoService extends BaseService {
|
|||||||
taskLogEntity: Repository<TaskLogEntity>;
|
taskLogEntity: Repository<TaskLogEntity>;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
taskInfoQueue: IQueue;
|
taskInfoQueue: TaskInfoQueue;
|
||||||
|
|
||||||
@App()
|
@App()
|
||||||
app: IMidwayWebApplication;
|
app: IMidwayWebApplication;
|
||||||
@ -42,9 +42,7 @@ export class TaskInfoService extends BaseService {
|
|||||||
if (task) {
|
if (task) {
|
||||||
const job = await this.exist(task.id);
|
const job = await this.exist(task.id);
|
||||||
if (job) {
|
if (job) {
|
||||||
await this.taskInfoQueue.queue.removeRepeatable(
|
await this.taskInfoQueue.removeRepeatable(JSON.parse(task.repeatConf));
|
||||||
JSON.parse(task.repeatConf)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
task.status = 0;
|
task.status = 0;
|
||||||
await this.taskInfoEntity.update(task.id, task);
|
await this.taskInfoEntity.update(task.id, task);
|
||||||
@ -73,8 +71,8 @@ export class TaskInfoService extends BaseService {
|
|||||||
async once(id) {
|
async once(id) {
|
||||||
const task = await this.taskInfoEntity.findOne({ id });
|
const task = await this.taskInfoEntity.findOne({ id });
|
||||||
if (task) {
|
if (task) {
|
||||||
await this.taskInfoQueue.queue.add(task, {
|
await this.taskInfoQueue.add(task, {
|
||||||
jobId: task.id,
|
jobId: task.id.toString(),
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
});
|
});
|
||||||
@ -86,8 +84,7 @@ export class TaskInfoService extends BaseService {
|
|||||||
* @param jobId
|
* @param jobId
|
||||||
*/
|
*/
|
||||||
async exist(jobId) {
|
async exist(jobId) {
|
||||||
console.log(jobId);
|
const result = await this.taskInfoQueue.getRepeatableJobs();
|
||||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
|
||||||
const ids = result.map(e => {
|
const ids = result.map(e => {
|
||||||
return e.id;
|
return e.id;
|
||||||
});
|
});
|
||||||
@ -112,26 +109,33 @@ export class TaskInfoService extends BaseService {
|
|||||||
if (params.status === 1) {
|
if (params.status === 1) {
|
||||||
const exist = await this.exist(params.id);
|
const exist = await this.exist(params.id);
|
||||||
if (exist) {
|
if (exist) {
|
||||||
await this.taskInfoQueue.queue.removeRepeatable(
|
await this.taskInfoQueue.removeRepeatable(
|
||||||
JSON.parse(params.repeatConf)
|
JSON.parse(params.repeatConf)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const jobOp = Object.assign(params);
|
const { every, limit, startDate, endDate, cron } = params;
|
||||||
await this.utils.removeEmptyP(jobOp);
|
const repeat = {
|
||||||
delete jobOp.repeatConf;
|
every,
|
||||||
const { opts } = await this.taskInfoQueue.queue.add(params, {
|
limit,
|
||||||
|
jobId: params.id,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
cron,
|
||||||
|
};
|
||||||
|
await this.utils.removeEmptyP(repeat);
|
||||||
|
const result = await this.taskInfoQueue.add(params, {
|
||||||
jobId: params.id,
|
jobId: params.id,
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
repeat: jobOp,
|
repeat,
|
||||||
});
|
});
|
||||||
if (!opts) {
|
if (!result) {
|
||||||
throw new Error('任务添加失败,可能由于格式不正确~');
|
throw new Error('任务添加失败,请检查任务配置');
|
||||||
}
|
}
|
||||||
// await transactionalEntityManager.update(TaskInfoEntity, params.id, {
|
// await transactionalEntityManager.update(TaskInfoEntity, params.id, {
|
||||||
// jobId: opts.jobId,
|
// jobId: opts.jobId,
|
||||||
// });
|
// });
|
||||||
repeatConf = opts;
|
repeatConf = result.opts;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (params.status === 1) {
|
if (params.status === 1) {
|
||||||
@ -159,9 +163,7 @@ export class TaskInfoService extends BaseService {
|
|||||||
const task = await this.taskInfoEntity.findOne({ id });
|
const task = await this.taskInfoEntity.findOne({ id });
|
||||||
const exist = await this.exist(task.id);
|
const exist = await this.exist(task.id);
|
||||||
if (exist) {
|
if (exist) {
|
||||||
await this.taskInfoQueue.queue.removeRepeatable(
|
await this.taskInfoQueue.removeRepeatable(JSON.parse(task.repeatConf));
|
||||||
JSON.parse(task.repeatConf)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
await this.taskInfoEntity.delete({ id });
|
await this.taskInfoEntity.delete({ id });
|
||||||
await this.taskLogEntity.delete({ taskId: id });
|
await this.taskLogEntity.delete({ taskId: id });
|
||||||
@ -237,12 +239,10 @@ export class TaskInfoService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
async getNextRunTime(jobId) {
|
async getNextRunTime(jobId) {
|
||||||
let nextRunTime;
|
let nextRunTime;
|
||||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
const result = await this.taskInfoQueue.getRepeatableJobs();
|
||||||
for (const task of result) {
|
const task = _.find(result, { id: jobId + '' });
|
||||||
if (task.id === jobId.toString()) {
|
if (task) {
|
||||||
nextRunTime = new Date(task.next);
|
nextRunTime = new Date(task.next);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nextRunTime;
|
return nextRunTime;
|
||||||
}
|
}
|
||||||
@ -261,25 +261,21 @@ export class TaskInfoService extends BaseService {
|
|||||||
/**
|
/**
|
||||||
* 刷新任务状态
|
* 刷新任务状态
|
||||||
*/
|
*/
|
||||||
async updateStatus() {
|
async updateStatus(jobId) {
|
||||||
const result = await this.taskInfoQueue.queue.getRepeatableJobs();
|
const result = await this.taskInfoQueue.getRepeatableJobs();
|
||||||
for (const job of result) {
|
const job = _.find(result, { id: jobId + '' });
|
||||||
const task = await this.taskInfoEntity.findOne({ id: job.id });
|
// @ts-ignore
|
||||||
if (task) {
|
const task = await this.taskInfoEntity.findOne({ id: job.id });
|
||||||
setTimeout(async () => {
|
const nextTime = await this.getNextRunTime(task.id);
|
||||||
// 2秒后清空任务
|
if (task) {
|
||||||
const nextTime = await this.getNextRunTime(task.id);
|
if (task.nextRunTime.getTime() == nextTime.getTime()) {
|
||||||
if (nextTime && nextTime.getTime() <= new Date().getTime() - 999) {
|
task.status = 0;
|
||||||
this.nativeQuery(
|
task.nextRunTime = nextTime;
|
||||||
'update task_info a set a.status = ?, a.updateTime = ? where a.id = ?',
|
this.taskInfoQueue.removeRepeatableByKey(job.key);
|
||||||
[0, new Date(), task.id]
|
} else {
|
||||||
);
|
task.nextRunTime = nextTime;
|
||||||
this.taskInfoQueue.queue.removeRepeatable(
|
|
||||||
JSON.parse(task.repeatConf)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
|
await this.taskInfoEntity.update(task.id, task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,12 +10,12 @@ export default (appInfo: EggAppInfo) => {
|
|||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
username: 'root',
|
username: 'root',
|
||||||
password: '123456',
|
password: '123123',
|
||||||
database: 'cool',
|
database: 'cool',
|
||||||
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
// 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
// 打印日志
|
// 打印日志
|
||||||
logging: true,
|
logging: false,
|
||||||
// 字符集
|
// 字符集
|
||||||
charset: 'utf8mb4',
|
charset: 'utf8mb4',
|
||||||
// 驱动
|
// 驱动
|
||||||
@ -30,5 +30,15 @@ export default (appInfo: EggAppInfo) => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config.cool = {
|
||||||
|
// redis为插件名称
|
||||||
|
redis: {
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '',
|
||||||
|
port: 6379,
|
||||||
|
db: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import * as orm from '@midwayjs/orm';
|
|||||||
import * as cool from '@cool-midway/core';
|
import * as cool from '@cool-midway/core';
|
||||||
// import * as wxpay from '@cool-midway/wxpay';
|
// import * as wxpay from '@cool-midway/wxpay';
|
||||||
import * as oss from '@cool-midway/oss';
|
import * as oss from '@cool-midway/oss';
|
||||||
// import * as redis from '@cool-midway/redis';
|
import * as redis from '@cool-midway/redis';
|
||||||
// import * as queue from '@cool-midway/queue';
|
import * as queue from '@cool-midway/queue';
|
||||||
// import * as alipay from '@cool-midway/alipay';
|
// import * as alipay from '@cool-midway/alipay';
|
||||||
// import * as socket from '@cool-midway/socket';
|
// import * as socket from '@cool-midway/socket';
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ import * as oss from '@cool-midway/oss';
|
|||||||
// oss插件,需要到后台配置之后才有用,默认是本地上传
|
// oss插件,需要到后台配置之后才有用,默认是本地上传
|
||||||
oss,
|
oss,
|
||||||
// 将缓存替换成redis
|
// 将缓存替换成redis
|
||||||
//redis,
|
redis,
|
||||||
// 队列
|
// 队列
|
||||||
//queue,
|
queue,
|
||||||
// 微信支付
|
// 微信支付
|
||||||
//wxpay,
|
//wxpay,
|
||||||
// 支付宝支付
|
// 支付宝支付
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user