import { t } from '../shared/i18n'; import { ServerUnaryCall, sendUnaryData } from '@grpc/grpc-js'; import { DeleteCronRequest, DeleteCronResponse } from '../protos/cron'; import { scheduleStacks } from './data'; import Logger from '../loaders/logger'; const delCron = ( call: ServerUnaryCall, callback: sendUnaryData, ) => { for (const id of call.request.ids) { if (scheduleStacks.has(id)) { Logger.info(t('[schedule][取消定时任务] 任务ID: %s'), id); // 防御性过滤历史调度栈中的空任务, // 否则对 null 调 cancel() 会让整个取消流程抛出 UNKNOWN 错误, // 进而导致 HTTP 端的 remove() 跳过 setCrontab(),造成 crontab.list 残留。 scheduleStacks .get(id) ?.filter((x) => x != null) .forEach((x) => { try { x.cancel(); } catch (error: any) { Logger.warn( t('[schedule][取消任务失败] 任务ID: %s, 错误: %s'), id, error?.message || error, ); } }); scheduleStacks.delete(id); } } callback(null, null); }; export { delCron };