fix: 修复 develop 调度锁、运行恢复与 Alpine 缓存并发 (#3070)

* fix: repair develop scheduler locks and runtime recovery

* test: wait for child reaping after verified termination

* fix: abort cron mutations when scheduler deletion fails
This commit is contained in:
whyour
2026-09-13 13:44:44 +08:00
committed by GitHub
parent 041a437453
commit 4eb27427f8
12 changed files with 350 additions and 46 deletions
+7 -27
View File
@@ -154,20 +154,14 @@ export default class CronService {
const tab = new Crontab({ ...doc, ...payload });
tab.saved = false;
tab.log_name = await this.getLogName(tab);
const newDoc = await this.updateDb(tab);
if (doc.isDisabled === 1 || isDemoEnv()) {
return newDoc;
return await this.updateDb(tab);
}
try {
await cronClient.delCron([String(newDoc.id)]);
} catch (error: any) {
this.logger.warn(
'[crontab] Failed to unregister cron job in scheduler:',
error?.message || error,
);
}
// Keep the DB snapshot unchanged if deletion has an uncertain outcome.
// Recovery uses that snapshot after this mutation releases its lock.
await cronClient.delCron([String(doc.id)]);
const newDoc = await this.updateDb(tab);
if (this.shouldUseCronClient(newDoc)) {
try {
@@ -305,15 +299,8 @@ export default class CronService {
public async remove(ids: number[]) {
return withSchedulerMutation(async () => {
await cronClient.delCron(ids.map(String));
await CrontabModel.destroy({ where: { id: ids } });
try {
await cronClient.delCron(ids.map(String));
} catch (error: any) {
this.logger.warn(
'[crontab] Failed to unregister cron job in scheduler:',
error?.message || error,
);
}
await this.setCrontab();
});
}
@@ -853,15 +840,8 @@ export default class CronService {
public async disabled(ids: number[]) {
return withSchedulerMutation(async () => {
await cronClient.delCron(ids.map(String));
await CrontabModel.update({ isDisabled: 1 }, { where: { id: ids } });
try {
await cronClient.delCron(ids.map(String));
} catch (error: any) {
this.logger.warn(
'[crontab] Failed to unregister cron job in scheduler:',
error?.message || error,
);
}
await this.setCrontab();
});
}