-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Do you want to request a feature or report a bug?
This is a bug
What is the current behavior?
Currently yarn terminates with exit code 1 when it receives a SIGTERM without waiting for the child to exit and without passing its child's exit status up the chain.
The issue that this stemmed from was about handling SIGTERM events (#3424) and was introduced in pull request #3789.
If the current behavior is a bug, please provide the steps to reproduce.
Create a simple express script:
const app = require('./express');
const server = app.listen(config.port, () => {
console.log(`server started`);
});
process.on('SIGTERM', () => {
server.close(() => {
setTimeout(() => {
process.exit(0);
}, 1000);
});
});
Note that the script uses setTimeout
to wait before exiting (as if it is waiting 1s for a client connection to end).
⇒ yarn start
yarn run v1.1.0
$ node src/index.js
server started
In another session run the following with the PID of that command:
kill $PID
Finally in that first session after it has exited:
⇒ echo $?
1
You can see that it exits immediately (not waiting 1s) and the error code is 1.
What is the expected behavior?
Expected behaviour is to do exactly as node would:
⇒ node src/index.js
server started
⇒ echo $?
0
This waits the 1s for the setTimeout
(we kill using kill $PID
in between the node and echo commands as above). You can also see we get the child's exit status (you can verify this by setting it to something else like process.exit(9)
and seeing it come out).
I see some comments in the code where it is questioning what we should do about this:
yarn/src/util/signal-handler.js
Lines 6 to 8 in daa599d
// We want to exit immediately here since `SIGTERM` means that | |
// If we lose stdout messages due to abrupt exit, shoot the messenger? | |
process.exit(1); // eslint-disable-line no-process-exit |
I think it's the child's job to decide what to do if a SIGTERM event is received. The parent should hand the signal to the child and wait to see if it exits. The only thing that I think Yarn should consider is whether there is a time limit that we would like to wait for naughty child processes that do not exit on time. Docker sets this to 10 seconds, whatever we set this to (if we do at all!!) we should make it a) clear and b) configurable.
One other thing: currently not sure what we do with SIGINT. I see weird stuff happening with that too (and I presume other signals?). Probably worth investigating signal handling more holistically?
Please mention your node.js, yarn and operating system version.
- Node version: 7 & 8
- Yarn version: 1.10.0
- macOS 16.3.0 and alpine