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

Fix thread leak in Python 3.7 #340 #356

Merged
merged 2 commits into from
Dec 11, 2018

Conversation

sbrandtb
Copy link
Contributor

@sbrandtb sbrandtb commented Dec 10, 2018

The leak is caused by the fact that in Python 3.7, the default behavior
of the ThreadingMixin is to use no daemon threads, but to request to
block on threads on close. Because of that, it collects references to
all created threads, creating the "leak":
https://github.com/python/cpython/blob/v3.7.0/Lib/socketserver.py#L661

Fix by setting daemon_threads to True, which in our case should be a
reasonable setting for all Python versions. Also, the new in Python 3.7
ThreadingHTTPServer stdlib class also sets it by default:
https://github.com/python/cpython/blob/v3.7.0/Lib/http/server.py#L144

Fixes #340

The leak is caused by the fact that in Python 3.7, the default behavior
of the `ThreadingMixin` is to use no daemon threads, but to request to
block on threads on close. Because of that, it collects references to
all created threads, creating the "leak":
https://github.com/python/cpython/blob/v3.7.0/Lib/socketserver.py#L661

* Python 3.7: `block_on_close` is `True`: https://github.com/python/cpython/blob/v3.7.0/Lib/socketserver.py#L635
* Python 3.6: `_block_on_close` is `False`: https://github.com/python/cpython/blob/v3.6.7/Lib/socketserver.py#L639
* Python 2.7: There is no `block_on_close`, thus no logic for collecting
  references: https://github.com/python/cpython/blob/v2.7.15/Lib/SocketServer.py#L582

Fix by setting `daemon_threads` to `True`, which in our case should be a
reasonable setting for all Python versions. Also, the new in Python 3.7
`ThreadingHTTPServer` stdlib class also sets it by default:
https://github.com/python/cpython/blob/v3.7.0/Lib/http/server.py#L144

Signed-off-by: Sebastian Brandt <sebastian.brandt@friday.de>
@sbrandtb sbrandtb force-pushed the fix_thread_leak_in_python_3_7 branch from b5e2040 to ef36e1c Compare December 10, 2018 16:43
@brian-brazil
Copy link
Contributor

Thanks for digging into this. Can you add a comment to the code explaining this briefly?

@sbrandtb
Copy link
Contributor Author

@brian-brazil Added some comments.

Signed-off-by: Sebastian Brandt <sebastian.brandt@friday.de>
@sbrandtb sbrandtb force-pushed the fix_thread_leak_in_python_3_7 branch from a9b7b6d to 51de8ba Compare December 11, 2018 08:27
@brian-brazil brian-brazil merged commit 5aa256d into prometheus:master Dec 11, 2018
@brian-brazil
Copy link
Contributor

Thanks!

wojons added a commit to wojons/dnslib that referenced this pull request Aug 13, 2020
#https://bugs.python.org/issue37788
    #prometheus/client_python#356
    daemon_threads = True # fix for python 3.7 please see links above for details
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

Successfully merging this pull request may close these issues.

HTTP server leaks memory in python3.7.1
2 participants