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 issue #1037, where the API client could hang indefinitely at
garbage collection.
This commit is contained in:
Fabian von Feilitzsch 2020-02-06 12:05:23 -05:00
parent 5181d2389e
commit 18d21df367

View File

@ -10,6 +10,7 @@
from __future__ import absolute_import
import atexit
import datetime
import json
import mimetypes
@ -77,11 +78,19 @@ class ApiClient(object):
# 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 @@ class ApiClient(object):
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