diff --git a/lib/process.js b/lib/process.js index b06073f..4132a02 100644 --- a/lib/process.js +++ b/lib/process.js @@ -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(); @@ -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( @@ -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); + } } }); } diff --git a/test/fixtures/init_error/a.ts b/test/fixtures/init_error/a.ts new file mode 100644 index 0000000..a410409 --- /dev/null +++ b/test/fixtures/init_error/a.ts @@ -0,0 +1,4 @@ +console.log("b") +export async function init() { + throw new Error("init error") +} diff --git a/test/fixtures/init_error/run.js b/test/fixtures/init_error/run.js new file mode 100644 index 0000000..507943a --- /dev/null +++ b/test/fixtures/init_error/run.js @@ -0,0 +1,4 @@ +const { init } = require('./dist/a.js') +init().then(() => { + process.send({ title: 'server-ready' }); +}); diff --git a/test/fixtures/init_error/tsconfig.json b/test/fixtures/init_error/tsconfig.json new file mode 100644 index 0000000..b3be0de --- /dev/null +++ b/test/fixtures/init_error/tsconfig.json @@ -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" + ] +} diff --git a/test/fixtures/unreject_error/a.ts b/test/fixtures/unreject_error/a.ts new file mode 100644 index 0000000..090a276 --- /dev/null +++ b/test/fixtures/unreject_error/a.ts @@ -0,0 +1 @@ +console.log("b") \ No newline at end of file diff --git a/test/fixtures/unreject_error/run.js b/test/fixtures/unreject_error/run.js index 522ca1e..ad59ae9 100644 --- a/test/fixtures/unreject_error/run.js +++ b/test/fixtures/unreject_error/run.js @@ -1,2 +1,2 @@ require('./dist/a.js') -process.send({ type: 'ready' }); +process.send({ title: 'server-ready' }); diff --git a/test/index.test.js b/test/index.test.js index 1ce828b..2c0a828 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -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); + }); + }); });