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

type_inference_provider does not properly clean up child processes on timeout #472

Closed
lisroach opened this issue Mar 31, 2021 · 2 comments
Closed

Comments

@lisroach
Copy link
Contributor

lisroach commented Mar 31, 2021

If the subprocess call to in type_inference_provider times out the child processes do not get immediately cleaned up:

ERROR:1:1: X002 raise TimeoutExpired(
ERROR:1:1: X002 subprocess.TimeoutExpired: Command 'pyre --noninteractive query "types(path='python/fixit/flake8/test.py')"' timed out after 0 seconds
ERROR:1:1: X002 .../lib/python3.8/subprocess.py:942: ResourceWarning: subprocess 881287 is still running
ERROR:1:1: X002 _warn("subprocess %s is still running" % self.pid,
ERROR:1:1: X002 ResourceWarning: Enable tracemalloc to get the object allocation traceback
ERROR:1:1: X002 sys:1: ResourceWarning: unclosed file <_io.BufferedReader name=3>
ERROR:1:1: X002 sys:1: ResourceWarning: unclosed file <_io.BufferedReader name=5>

When running over a large directory a new process is spawned per path so this can become problematic for scaling.

I believe the processes don't get killed by the TimeoutExpired being raised because shell=True is in use (

command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
).
StackOverflow suggests it's because the blocking process is a child of the shell process (https://stackoverflow.com/questions/48763362/python-subprocess-kill-with-timeout).

I'm trying to get a repro of this externally but haven't done so yet.

I plan to work on this, but am opening the issue for discussion and tracking.

@zsol
Copy link
Member

zsol commented Apr 1, 2021

Easiest way to repro is probably to add a fake pyre wrapper on your path that sleeps for a minute before delegating to real pyre :)

@lisroach
Copy link
Contributor Author

lisroach commented Apr 1, 2021

@zsol that is a great idea, I got something working before I noticed it though:

<test_libcst.py>

from pathlib import Path
from libcst.metadata.type_inference_provider import TypeInferenceProvider

cache = TypeInferenceProvider.gen_cache(Path("."), ["test.py"], 0)

And running with:
python3 -Wdefault test_libcst.py

Triggers the warning like:

(libcst-env) lisroach@lisroach-mbp libCST % python3 -Wdefault test_libcst.py
Traceback (most recent call last):
  File "test_libcst.py", line 4, in <module>
    cache = TypeInferenceProvider.gen_cache(Path("."), ["test.py"], 0)
  File "/Users/lisroach/LibCST/libcst/metadata/type_inference_provider.py", line 64, in gen_cache
    raise exc
  File "/Users/lisroach/LibCST/libcst/metadata/type_inference_provider.py", line 62, in gen_cache
    stdout, stderr, return_code = run_command(cmd, timeout=timeout)
  File "/Users/lisroach/LibCST/libcst/metadata/type_inference_provider.py", line 108, in run_command
    stdout, stderr = process.communicate(timeout=timeout)
  File "/opt/homebrew/Cellar/python37/3.7.5_3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 964, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/opt/homebrew/Cellar/python37/3.7.5_3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1710, in _communicate
    skip_check_and_raise=True)
  File "/opt/homebrew/Cellar/python37/3.7.5_3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1011, in _check_timeout
    stderr=b''.join(stderr_seq) if stderr_seq else None)
subprocess.TimeoutExpired: Command 'pyre --noninteractive query "types(path='test.py')"' timed out after 0 seconds
/opt/homebrew/Cellar/python37/3.7.5_3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py:883: ResourceWarning: subprocess 35820 is still running
  ResourceWarning, source=self)
sys:1: ResourceWarning: unclosed file <_io.BufferedReader name=3>
sys:1: ResourceWarning: unclosed file <_io.BufferedReader name=5>

Which leads to a zombie process like:
lisroach 35820 0.0 0.0 0 0 s001 Z+ 4:03PM 0:00.00 (Python)

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