From 9a5138a3f7b4811c7b63028c40eb9887c2a82750 Mon Sep 17 00:00:00 2001 From: Fabian von Feilitzsch Date: Thu, 6 Feb 2020 12:05:23 -0500 Subject: [PATCH] Cleanup ThreadPool with atexit rather than __del__ This removes the __del__ function from the generated Python client, and replaces it with a cleanup function. When a ThreadPool is created, the cleanup function is registered with the atexit module. This PR also allows the client to be used as a context manager, which will automatically clean up after itself rather than having to wait til process exit. This fixes #1037, where the API client could hang indefinitely at garbage collection. --- kubernetes/client/api_client.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index 498517651e..fde1a17f48 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -10,6 +10,7 @@ from __future__ import absolute_import +import atexit import datetime import json import mimetypes @@ -77,11 +78,19 @@ def __init__(self, configuration=None, header_name=None, header_value=None, # Set default User-Agent. self.user_agent = 'OpenAPI-Generator/11.0.0-snapshot/python' - def __del__(self): + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.close() + + def close(self): if self._pool: self._pool.close() self._pool.join() self._pool = None + if hasattr(atexit, 'unregister'): + atexit.unregister(self.close) @property def pool(self): @@ -89,6 +98,7 @@ def pool(self): avoids instantiating unused threadpool for blocking clients. """ if self._pool is None: + atexit.register(self.close) self._pool = ThreadPool(self.pool_threads) return self._pool