mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-15 19:57:07 +08:00
fix: 修复任务生命周期与调度就绪,优化执行和构建开销 (#3069)
* fix: harden task lifecycle and scheduler readiness * fix: confine log writes to the configured log directory * fix: verify complete build artifacts and untracked inputs * fix: reconcile scheduler state and make stop win startup races * fix: isolate cron generations and serialize scheduler recovery
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const vm = require('node:vm');
|
||||
const ts = require('typescript');
|
||||
const source = fs.readFileSync('back/app.ts', 'utf8');
|
||||
const entry = source.indexOf('\nconst app = new Application();');
|
||||
assert.ok(entry > 0, 'application entry point exists');
|
||||
const compiled = ts.transpileModule(
|
||||
source.slice(0, entry) + '\nmodule.exports = Application;',
|
||||
{
|
||||
compilerOptions: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES2022,
|
||||
esModuleInterop: true,
|
||||
},
|
||||
},
|
||||
).outputText;
|
||||
function create(env) {
|
||||
const calls = [];
|
||||
const cluster = {
|
||||
fork(options) {
|
||||
const worker = {
|
||||
id: calls.length + 1,
|
||||
process: { pid: 100 + calls.length },
|
||||
};
|
||||
calls.push({ options, inherited: { ...env, ...options }, worker });
|
||||
return worker;
|
||||
},
|
||||
};
|
||||
const module = { exports: {} };
|
||||
const sandbox = {
|
||||
module,
|
||||
exports: module.exports,
|
||||
process: { env },
|
||||
require(name) {
|
||||
if (name === 'cluster') return cluster;
|
||||
if (name === 'express') return () => ({ use() {} });
|
||||
return {};
|
||||
},
|
||||
};
|
||||
vm.runInNewContext(compiled, sandbox);
|
||||
return { app: new module.exports(), calls };
|
||||
}
|
||||
test('PM2-managed primary disables only inherited worker APM and keeps worker metadata', () => {
|
||||
const env = { pm_id: '0', pmx: 'true', CUSTOM_VALUE: 'kept' };
|
||||
const { app, calls } = create(env);
|
||||
for (const role of ['grpc', 'http']) app.forkWorker(role);
|
||||
assert.deepEqual(
|
||||
calls.map((x) => ({ ...x.options })),
|
||||
[
|
||||
{ SERVICE_TYPE: 'grpc', pmx: 'false' },
|
||||
{ SERVICE_TYPE: 'http', pmx: 'false' },
|
||||
],
|
||||
);
|
||||
assert.equal(env.pmx, 'true');
|
||||
assert.equal(calls[0].inherited.CUSTOM_VALUE, 'kept');
|
||||
for (const call of calls) {
|
||||
const entry = app.workerMetadataMap.get(call.worker.id);
|
||||
assert.equal(entry.pid, call.worker.process.pid);
|
||||
assert.equal(entry.serviceType, call.options.SERVICE_TYPE);
|
||||
}
|
||||
});
|
||||
test('worker APM opt-in restores inherited PM2 settings, including explicit disable', () => {
|
||||
for (const pmx of ['true', 'false']) {
|
||||
const { app, calls } = create({ pm_id: '0', pmx, QL_WORKER_APM: 'true' });
|
||||
app.forkWorker('http');
|
||||
assert.equal(Object.hasOwn(calls[0].options, 'pmx'), false);
|
||||
assert.equal(calls[0].inherited.pmx, pmx);
|
||||
}
|
||||
});
|
||||
test('standalone startup does not introduce a PM2-specific override', () => {
|
||||
const { app, calls } = create({ CUSTOM_VALUE: 'kept' });
|
||||
app.forkWorker('grpc');
|
||||
assert.deepEqual({ ...calls[0].options }, { SERVICE_TYPE: 'grpc' });
|
||||
assert.equal(calls[0].inherited.CUSTOM_VALUE, 'kept');
|
||||
});
|
||||
test('replacement workers receive the same monitoring policy', () => {
|
||||
const { app, calls } = create({ pm_id: '0', pmx: 'true' });
|
||||
app.forkWorker('grpc');
|
||||
app.forkWorker('grpc');
|
||||
assert.equal(calls[1].inherited.pmx, 'false');
|
||||
assert.notEqual(calls[0].worker.id, calls[1].worker.id);
|
||||
});
|
||||
Reference in New Issue
Block a user