Description
Since a transport
object may be passed into a client constructor, the client does not close that transport in when the client object is deleted. This results in leaking socket resources in programs that create client objects dynamically.
Proposed design:
Add the following two ways to explicitly clean-up sockets owned by the client: (1, preferred) allow clients to act as a context manager and (2) a close() method.
-
Context manager
Allow all client objects to be used as a context manager. Call close() on the client in the exit method to clean up sockets owned by the client.
In code samples with short-lived clients, this is the cleanup method we should recommend.
Example:
from google.cloud import bigquery_datatransfer_v1
with bigquery_datatransfer_v1.DataTransferServiceClient() as client:
print(client.get_transfer_run('some run id').state)
-
close()
methodAdd a
close()
method to all client objects. When called, clean up sockets owned by the client, including the transport channel.Example:
from google.cloud import bigquery_datatransfer_v1
client = bigquery_datatransfer_v1.DataTransferServiceClient()
print(client.get_transfer_run('some run id').state)
client.close() # clean up any open sockets
References:
- go/closable-clients-python (Google internal)
- [BigQuery Data Transfer Service, all GAPIC clients]: provide a close() method and context manager to clean up client-owned resources google-cloud-python#9457
- fix(bigquery): add close() method to client for releasing open sockets google-cloud-python#9894
- Connections stay in CLOSE_WAIT state on using kms_v1.KeyManagementServiceClient python-kms#2