mirror of
https://github.com/whyour/qinglong.git
synced 2026-11-02 15:56:59 +08:00
fix: skip new scheduled triggers while a single-instance task is active (#3101)
* fix: skip active single-instance scheduled executions * fix: recover stale single-instance scheduled tasks * test: remove obsolete single-instance replacement assertions --------- Co-authored-by: Patrick Gu <username@users.noreply.github.com> Co-authored-by: whyour <imwhyour@gmail.com>
This commit is contained in:
co-authored by
Patrick Gu
whyour
parent
d895fbba36
commit
da9c6a6bbb
@@ -4,75 +4,6 @@ const load = require('../helpers/load-security-module.cjs');
|
||||
|
||||
const logger = { info() {}, error() {} };
|
||||
|
||||
function cronFixture(killTask) {
|
||||
const events = [];
|
||||
const { runCron } = load('back/shared/runCron.ts', {
|
||||
'cross-spawn': {
|
||||
spawn: () => {
|
||||
events.push('spawn');
|
||||
return {};
|
||||
},
|
||||
},
|
||||
'./childProcess': {
|
||||
observeChildProcess: () => ({ completed: Promise.resolve({ code: 0 }) }),
|
||||
asError: (e) => e,
|
||||
},
|
||||
'./pLimit': {
|
||||
runWithCronLimit: async (_, fn) => fn(),
|
||||
removeQueuedCron: () => events.push('release'),
|
||||
},
|
||||
'../loaders/logger': logger,
|
||||
'../config/util': { killTask },
|
||||
'../data/cron': {
|
||||
CrontabModel: {
|
||||
findOne: async () => ({
|
||||
pid: 100,
|
||||
status: 0,
|
||||
allow_multiple_instances: 0,
|
||||
}),
|
||||
update: async () => events.push('idle'),
|
||||
},
|
||||
CrontabStatus: { running: 0, idle: 1, queued: 3 },
|
||||
},
|
||||
'../data/runningInstance': {
|
||||
RunningInstanceModel: { update: async () => events.push('stopped') },
|
||||
InstanceStatus: { running: 0, stopped: 2 },
|
||||
},
|
||||
});
|
||||
return { run: () => runCron('ignored', { id: '1' }), events };
|
||||
}
|
||||
|
||||
test('single-instance replacement does not spawn or finalize when termination fails', async () => {
|
||||
const f = cronFixture(async () => {
|
||||
throw Error('EPERM');
|
||||
});
|
||||
await f.run();
|
||||
assert.deepEqual(f.events, ['release']);
|
||||
});
|
||||
|
||||
test('single-instance replacement waits for verified exit before spawning', async () => {
|
||||
let finish, entered, verified;
|
||||
const pending = new Promise((resolve) => {
|
||||
entered = resolve;
|
||||
});
|
||||
const gate = new Promise((resolve) => {
|
||||
finish = resolve;
|
||||
});
|
||||
const f = cronFixture(async (pid, wait) => {
|
||||
assert.equal(pid, 100);
|
||||
verified = wait;
|
||||
entered();
|
||||
await gate;
|
||||
});
|
||||
const running = f.run();
|
||||
await pending;
|
||||
assert.deepEqual(f.events, []);
|
||||
finish();
|
||||
await running;
|
||||
assert.equal(verified, true);
|
||||
assert.deepEqual(f.events, ['stopped', 'idle', 'spawn', 'release']);
|
||||
});
|
||||
|
||||
function subscriptionFixture(killTask) {
|
||||
const updates = [];
|
||||
const Service = load('back/services/subscription.ts', {
|
||||
|
||||
Reference in New Issue
Block a user