-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Self-service
- I'd be willing to implement a fix
Describe the bug
(The code bellow describe the content of the repo available for reproduction)
With a simple express server handling a SIGTERM by waiting 3000ms before shutting down:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hello, World!')
})
const timeout = 3000;
function handle(signal) {
console.log(`Received ${signal}, shutting server in ${timeout} ms`);
return new Promise(resolve => {
setTimeout(() => {
console.log('End of timeout, shutting down server now.');
resolve();
process.exit(0);
}, timeout);
});
}
process.on('SIGTERM', handle);
app.listen(3000, () => {
console.log('Server listening on port 3000')
})Yarn will transmit the signal to its child process, which will call its handler function as expected.
But yarn will not wait for its child process to die before exiting. In a Docker context, it means the container will exit as well (yarn being PID 1)
So this container as a k8s pod will not gracefully shut down.
To reproduce
Clone repo and launch the container with Yarn:
git clone git@github.com:brian-xu-vlt/poc-yarn-issue.git
cd poc-yarn-issue
docker build -t poc . && docker run -it --rm -l 'poc' poc
In another terminal tab, kill the container:
docker kill --signal="SIGTERM" $(docker ps -q --filter=label="poc")
Will kill the container immediately, not waiting for 3000ms as expected.
For context, use NPM instead:
docker build -f Dockerfile.NPM -t poc . && docker run -it --rm -l 'poc' poc
In another terminal tab, kill the container:
docker kill --signal="SIGTERM" $(docker ps -q --filter=label="poc")
Will wait for 3000ms as expected.
Environment
Docker version 20.10.21, build baeda1f82a
with node:16.18.1-alpine image
yarn 3.3.1Additional context
Can be reproduced locally too (i.e. without docker) by running yarn start and find the pid of yarn process, then send a SIGTERM to it. It will leave the underlying node process as an orphan process, which means its output after the 3000ms will go to the terminal in the prompt, after yarn has exited:
