I'm writing test for electron application in typescript.
Inside application there are register listener for SIGTERM
process.on('SIGTERM', async () => {
console.log('before exit');
await this.exit(); //some inner function can't reach this statement anyway
});
Locally everything fine, but on CI when app running inside docker container looks like it didn't receive SIGTERM
.
For starting application I'm using child_process.spawn
import type { ChildProcess } from 'child_process';
let yarnStart: ChildProcess = spawn('yarn', 'start', { shell: true });
// 'start' is just script in package.json
I try to kill application three different way and none of them works. Application didn't receive SIGTERM no before exit
and after manually stopping ci-build in final-step ps aux
showing my process.
// 1-way
yarnStart.kill('SIGTERM');
// 2-way
process.kill(yarnStart.pid, 'SIGTERM');
// 3-way
import { execSync } from 'child_process';
execSync(`kill -15 ${yarnStart.pid}`);
Why nodejs can't properly send SIGTERM
inside docker container?
Only difference - locally I have debian-9(stretch) and image based on debian-10(buster). Same nodejs version 12.14.1. I will try to build container with stretch to see how it will behave, but skeptical about that this will help.
UPD
There is kind of difference in processes initiation(due to running scripts on CI in container, any instruction runs with /bin/sh -c
)
when you execute ps aux
you will see
//locally
myuser 101457 1.3 0.1 883544 58968 pts/8 Sl+ 10:32 0:00 /usr/bin/node /usr/share/yarn/bin/yarn.js start
myuser 101468 1.6 0.2 829316 69456 pts/8 Sl+ 10:32 0:00 /usr/bin/node /usr/share/yarn/lib/cli.js start
myuser 101479 1.6 0.2 829576 69296 pts/8 Sl+ 10:32 0:00 /usr/bin/node /usr/share/yarn/lib/cli.js start:debug
myuser 101490 0.2 0.0 564292 31140 pts/8 Sl+ 10:32 0:00 /usr/bin/node /home/myuser/myrepo/electron-app/node_modules/.bin/electron -r ts-node/register ./src/main.ts
myuser 101497 143 1.4 9215596 485132 pts/8 Sl+ 10:32 0:35 /home/myuser/myrepo/node_modules/electron/dist/electron -r ts-node/register ./src/main.ts
//container
root 495 0.0 0.0 2392 776 ? S 09:05 0:00 /bin/sh -c yarn start
root 496 1.0 0.2 893240 74336 ? Sl 09:05 0:00 /usr/local/bin/node /opt/yarn-v1.22.5/bin/yarn.js start
root 507 1.7 0.2 885588 68652 ? Sl 09:05 0:00 /usr/local/bin/node /opt/yarn-v1.22.5/lib/cli.js start
root 518 0.0 0.0 2396 712 ? S 09:05 0:00 /bin/sh -c yarn start:debug
root 519 1.7 0.2 885336 68608 ? Sl 09:05 0:00 /usr/local/bin/node /opt/yarn-v1.22.5/lib/cli.js start:debug
root 530 0.0 0.0 2396 780 ? S 09:05 0:00 /bin/sh -c electron -r ts-node/register ./src/main.ts
root 531 0.3 0.0 554764 32080 ? Sl 09:05 0:00 /usr/local/bin/node /opt/ci/jobfolder/job_id_423/electron-app/node_modules/.bin/electron -r ts-node/register ./src/main.ts
root 538 140 1.5 9072388 520824 ? Sl 09:05 0:26 /opt/ci/jobfolder/job_id_423/node_modules/electron/dist/electron -r ts-node/register ./src/main.ts
And actually killing process with
// 1-way
yarnStart.kill('SIGTERM');
works but it kills only /bin/sh -c yarn start
and his child_process /usr/local/bin/node /opt/yarn-v1.22.5/bin/yarn.js start
that actually spawn application still hanging
/bin/sh -c
which comes with a load of problems, one of them notably that you’ll never see a signal in your application. And descendant processes create they own/bin/sh -c
I find a solution in https://stackoverflow.com/a/33556110/4577788
Also find alternative solution(but it didn't work for me, maybe becaus of specifics of nodejs execution). You can kill all the processes belonging to the same process tree using the Process Group ID. More datailed info can be found here https://stackoverflow.com/a/15139734/4577788
When I try to execute
execSync('kill -- -942');
orexecSync('kill -- "-942"');
Error occure
kill: illegal number -
, didn't find why it occure and hove to fix it.