mirror of
https://github.com/whyour/qinglong.git
synced 2026-07-01 04:40:38 +08:00
Fix task duplication: add single/multi-instance support with UI configuration and stop all running instances (#2837)
* Initial plan * Stop running tasks before starting new scheduled instance Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add multi-instance support and fix stop to kill all running instances - Add allow_multiple_instances field to Crontab model (default: 0 for single instance) - Add validation for new field in commonCronSchema - Add getAllPids and killAllTasks utility functions - Update stop method to kill ALL running instances of a task - Update runCron to respect allow_multiple_instances config - Backward compatible: defaults to single instance mode Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add UI support for allow_multiple_instances configuration - Add allow_multiple_instances field to ICrontab interface - Add instance mode selector in task creation/edit modal - Add translations for instance mode in Chinese and English - Default to single instance mode for backward compatibility Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add allow_multiple_instances column migration and optimize db.ts - Add allow_multiple_instances column to Crontabs table migration - Refactor migration code to use data-driven approach - Replace 11 individual try-catch blocks with single loop - Improve code maintainability and readability Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
@@ -2,10 +2,45 @@ import { spawn } from 'cross-spawn';
|
||||
import taskLimit from './pLimit';
|
||||
import Logger from '../loaders/logger';
|
||||
import { ICron } from '../protos/cron';
|
||||
import { CrontabModel, CrontabStatus } from '../data/cron';
|
||||
import { killTask } from '../config/util';
|
||||
|
||||
export function runCron(cmd: string, cron: ICron): Promise<number | void> {
|
||||
return taskLimit.runWithCronLimit(cron, () => {
|
||||
return new Promise(async (resolve: any) => {
|
||||
// Check if the cron is already running and stop it (only if multiple instances are not allowed)
|
||||
try {
|
||||
const existingCron = await CrontabModel.findOne({
|
||||
where: { id: Number(cron.id) },
|
||||
});
|
||||
|
||||
// Default to single instance mode (0) for backward compatibility
|
||||
const allowMultipleInstances =
|
||||
existingCron?.allow_multiple_instances === 1;
|
||||
|
||||
if (
|
||||
!allowMultipleInstances &&
|
||||
existingCron &&
|
||||
existingCron.pid &&
|
||||
(existingCron.status === CrontabStatus.running ||
|
||||
existingCron.status === CrontabStatus.queued)
|
||||
) {
|
||||
Logger.info(
|
||||
`[schedule][停止已运行任务] 任务ID: ${cron.id}, PID: ${existingCron.pid}`,
|
||||
);
|
||||
await killTask(existingCron.pid);
|
||||
// Update the status to idle after killing
|
||||
await CrontabModel.update(
|
||||
{ status: CrontabStatus.idle, pid: undefined },
|
||||
{ where: { id: Number(cron.id) } },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
Logger.error(
|
||||
`[schedule][检查已运行任务失败] 任务ID: ${cron.id}, 错误: ${error}`,
|
||||
);
|
||||
}
|
||||
|
||||
Logger.info(
|
||||
`[schedule][开始执行任务] 参数 ${JSON.stringify({
|
||||
...cron,
|
||||
|
||||
Reference in New Issue
Block a user