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

Misbehaving processes aren't killed with --race #139

Open
whymarrh opened this issue Aug 2, 2018 · 2 comments
Open

Misbehaving processes aren't killed with --race #139

whymarrh opened this issue Aug 2, 2018 · 2 comments

Comments

@whymarrh
Copy link

whymarrh commented Aug 2, 2018

Given the following package.json file (cruft removed):

{
  "scripts": {
    "a": "test/programs/a",
    "b": "test/programs/b",
    "sleep10s": "sleep 10"
  },
  "devDependencies": {
    "npm-run-all": "^4.1.3"
  }
}

Racing a, b, and sleep10s should terminate a and b when sleep 10 exits after 10 seconds but instead run-p hangs:

$ ./node_modules/.bin/run-p --race a b sleep10s

> example@1.0.0 a /Users/jim/example
> test/programs/a


> example@1.0.0 b /Users/jim/example
> test/programs/b


> example@1.0.0 sleep10s /Users/jim/example
> sleep 10

GRACEFUL
IGNORING SIGNAL

This is because b doesn't correctly handle SIGTERM and needs to be sent SIGKILL.

Racing tasks that do correctly respond to SIGTERM works fine:

$ ./node_modules/.bin/run-p --race a a a sleep10s

> example@1.0.0 sleep10s /Users/jim/example
> sleep 10


> example@1.0.0 a /Users/jim/example
> test/programs/a


> example@1.0.0 a /Users/jim/example
> test/programs/a


> example@1.0.0 a /Users/jim/example
> test/programs/a

GRACEFUL
GRACEFUL
GRACEFUL

What's worse is that further sending SIGINT to run-p will cause it to exit (with 130) and orphan b. The process tree while hanging:

-+= 74470 jim node ./node_modules/.bin/run-p --race a a a b sleep10s
 \-+- 74474 jim npm   
   \--- 74480 jim /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -u test/programs/b

The process tree after SIGINT:

-+= 00001 root /sbin/launchd
 \-+- 74474 jim npm
   \--- 74480 jim /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -u test/programs/b

Example programs

test/programs/a (correctly responds to SIGTERM):

#!/usr/bin/env python -u

from __future__ import print_function
import signal
import sys

def graceful_exit(sig, frame):
    print('GRACEFUL')
    print('GRACEFUL', file=open("was-graceful.log", "wt"))
    sys.exit(0)

signal.signal(signal.SIGINT,  graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)
signal.pause()

test/programs/b (incorrectly ignores SIGTERM):

#!/usr/bin/env python -u

from __future__ import print_function
import signal
import sys
import time

def ignore_signal(sig, frame):
    print('IGNORING SIGNAL')
    while True:
        time.sleep(42)

signal.signal(signal.SIGINT,  ignore_signal)
signal.signal(signal.SIGTERM, ignore_signal)
signal.pause()

Possible solution

Based on a bit of research, I think a more correct way to kill child processes would be to send SIGTERM to the children (not the the whole trees, just immediate children) and after some timeout send SIGKILL to the tree. This is what a few init systems will do. It should also be possible to handle signals and ensure that all child processes are cleaned up before exiting.

Related issues

@whymarrh
Copy link
Author

whymarrh commented Aug 2, 2018

https://github.com/kimmobrunfeldt/concurrently/issues/155 is a similar issue with concurrently

@webartoli
Copy link

webartoli commented Mar 28, 2024

Solved installing package procps.
I have figured out that on *nix package an additional package procps is required and can be installed with:

# debian/ubuntu based distro
$ [sudo] apt install -y procps

# alpine based distro
$ apk add -y procps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants