增加停止定时任务功能

This commit is contained in:
whyour 2021-05-10 15:45:52 +08:00
parent fa3d73ac9a
commit 5ef327692b
5 changed files with 114 additions and 13 deletions

View File

@ -69,6 +69,24 @@ export default (app: Router) => {
},
);
route.put(
'/crons/stop',
celebrate({
body: Joi.array().items(Joi.string().required()),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cronService = Container.get(CronService);
const data = await cronService.stop(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
route.put(
'/crons/disable',
celebrate({

View File

@ -8,6 +8,7 @@ export class Crontab {
_id?: string;
status?: CrontabStatus;
isSystem?: 1 | 0;
pid?: number;
constructor(options: Crontab) {
this.name = options.name;
@ -19,6 +20,7 @@ export class Crontab {
this.status = options.status || CrontabStatus.idle;
this.timestamp = new Date().toString();
this.isSystem = options.isSystem || 0;
this.pid = options.pid;
}
}

View File

@ -22,13 +22,13 @@ const initData = [
name: '删除日志',
command: 'ql rmlog 7',
schedule: '30 7 */7 * *',
status: CrontabStatus.disabled,
status: CrontabStatus.idle,
},
{
name: '互助码',
command: 'ql code',
schedule: '30 7 * * *',
status: CrontabStatus.disabled,
status: CrontabStatus.idle,
},
];

View File

@ -121,6 +121,25 @@ export default class CronService {
});
}
public async stop(ids: string[]) {
this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => {
for (let i = 0; i < docs.length; i++) {
const doc = docs[i];
this.runSingle(doc);
if (doc.pid) {
exec(`kill -9 ${doc.pid}`, (err, stdout, stderr) => {
let logFile = `${config.manualLogPath}${doc._id}.log`;
this.cronDb.update(
{ _id: doc._id },
{ $set: { status: CrontabStatus.idle } },
);
fs.appendFileSync(logFile, `\n\n${stderr}\n${stdout}\n执行结束...`);
});
}
}
});
}
private async runSingle(cron: Crontab) {
let { _id, command } = cron;
@ -140,7 +159,10 @@ export default class CronService {
}
const cmd = spawn(cmdStr, { shell: true });
this.cronDb.update({ _id }, { $set: { status: CrontabStatus.running } });
this.cronDb.update(
{ _id },
{ $set: { status: CrontabStatus.running, pid: cmd.pid } },
);
cmd.stdout.on('data', (data) => {
this.logger.silly(`stdout: ${data}`);

View File

@ -23,6 +23,7 @@ import {
EditOutlined,
StopOutlined,
DeleteOutlined,
PauseCircleOutlined,
} from '@ant-design/icons';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
@ -43,12 +44,14 @@ enum OperationName {
'启用',
'禁用',
'运行',
'停止',
}
enum OperationPath {
'enable',
'disable',
'run',
'stop',
}
const Crontab = () => {
@ -120,6 +123,7 @@ const Crontab = () => {
align: 'center' as const,
render: (text: string, record: any, index: number) => (
<Space size="middle">
{record.status !== CrontabStatus.running && (
<Tooltip title="运行">
<a
onClick={() => {
@ -129,6 +133,18 @@ const Crontab = () => {
<PlayCircleOutlined />
</a>
</Tooltip>
)}
{record.status === CrontabStatus.running && (
<Tooltip title="停止">
<a
onClick={() => {
stopCron(record, index);
}}
>
<PauseCircleOutlined />
</a>
</Tooltip>
)}
<Tooltip title="日志">
<a
onClick={() => {
@ -248,6 +264,42 @@ const Crontab = () => {
});
};
const stopCron = (record: any, index: number) => {
Modal.confirm({
title: '确认停止',
content: (
<>
{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning">
{record.name}
</Text>{' '}
</>
),
onOk() {
request
.put(`${config.apiPrefix}crons/stop`, { data: [record._id] })
.then((data: any) => {
if (data.code === 200) {
const result = [...value];
result.splice(index, 1, {
...record,
status: CrontabStatus.idle,
});
setValue(result);
} else {
notification.error({
message: data,
});
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
const enabledOrDisabledCron = (record: any, index: number) => {
Modal.confirm({
title: `确认${
@ -534,9 +586,16 @@ const Crontab = () => {
>
</Button>
<Button type="primary" onClick={() => operateCrons(2)}>
<Button
type="primary"
style={{ marginRight: 8 }}
onClick={() => operateCrons(2)}
>
</Button>
<Button type="primary" onClick={() => operateCrons(3)}>
</Button>
<span style={{ marginLeft: 8 }}>
<a>{selectedRowIds?.length}</a>