Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: stop restart when last boot fail #23

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions lib/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
}
let runChild;
let onServerReadyCallback;
/**
* 记录上一次启动状态, undefined 代表未启动
* 有可能自定义启动入口不会触发 server-ready
* 只在 --keepalive 下有效
*/
let lastBootstrapStatus = undefined;

function innerFork(isFirstFork = false) {
const startTime = Date.now();
Expand All @@ -105,14 +111,19 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
Date.now() - startTime
));
runChild.removeListener('message', onServerReady);
lastBootstrapStatus = true;
}
} catch (err) {
console.error(err);
lastBootstrapStatus = false;
}
};
runChild.on('message', onServerReady);
if (runArgs.includes('--keepalive')) {
runChild.once('exit', code => {
if (code !== 0) {
lastBootstrapStatus = false;
}
if (code === CHILD_PROCESS_EXCEPTION_EXIT_CODE) {
output(colors.red('*'.repeat(120)));
output(
Expand All @@ -124,10 +135,13 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
);
output('Please make sure to handle it.');
output(
'The --keepalive parameter was enabled, we will do our best to ensure the process remains normal..'
'The --keepalive parameter was enabled, we will do our best to ensure the process remains normal.'
);
output(colors.red('*'.repeat(120)));
innerFork(false);
if (lastBootstrapStatus === undefined || lastBootstrapStatus) {
// 只有上一次启动成功了,才继续保活拉起,如果启动就失败了,就停止重启
innerFork(false);
}
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/init_error/a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
console.log("b")
export async function init() {
throw new Error("init error")
}
4 changes: 4 additions & 0 deletions test/fixtures/init_error/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const { init } = require('./dist/a.js')
init().then(() => {
process.send({ title: 'server-ready' });
});
21 changes: 21 additions & 0 deletions test/fixtures/init_error/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es2018", // target es2018
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"inlineSourceMap":true,
"noImplicitThis": true,
"noUnusedLocals": true,
"stripInternal": true,
"skipLibCheck": true,
"pretty": true,
"outDir": "dist"
},
"exclude": [
"dist",
"node_modules",
"test"
]
}
1 change: 1 addition & 0 deletions test/fixtures/unreject_error/a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("b")
2 changes: 1 addition & 1 deletion test/fixtures/unreject_error/run.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
require('./dist/a.js')
process.send({ type: 'ready' });
process.send({ title: 'server-ready' });
28 changes: 28 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,32 @@ describe('/test/index.js', () => {
}, 3000);
});
});

it('should not restart when bootstrap fail in keepalive mode', async () => {
// prepare
const runPath = join(__dirname, 'fixtures/init_error');
await removeFile([
join(runPath, 'dist/a.js'),
]);

const cp = await execa('node', [mtscPath, '--watch', '--run', './run.js', '--keepalive'], {
cwd: runPath,
});

await new Promise((resolve, reject) => {
cp.on('exit', code => {
try {
expect(existsSync(join(runPath, 'dist/a.js'))).toBeTruthy();
expect(readFileSync(join(runPath, 'dist/a.js'), 'utf-8')).toMatch(/"b"/);
resolve();
} catch (err) {
reject(err);
}
});

setTimeout(() => {
cp.kill();
}, 3000);
});
});
});
Loading