Skip to content

Commit f210751

Browse files
author
Ian Cordasco
committed
Close streamed requests explicitly
If we don't explicitly close a response after streaming its download, then we can run into HTTPConnectionPool full warnings. It also will hurt performance if we have to continuously create new sockets for new responses. Calling close will return the connection to the pool so it can be reused. Note this is only necessary when streaming a response. If we don't stream it, then requests will return the connection to the pool for us. Change-Id: I803bd4dd0e769c233501d5e5ff07a19705fbe233 Closes-bug: 1341777
1 parent aebbcff commit f210751

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

glanceclient/common/http.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ def chunk_body(body):
236236
if content_type == 'application/octet-stream':
237237
# Do not read all response in memory when
238238
# downloading an image.
239-
body_iter = resp.iter_content(chunk_size=CHUNKSIZE)
239+
body_iter = _close_after_stream(resp, CHUNKSIZE)
240240
self.log_http_response(resp)
241241
else:
242242
content = resp.content
@@ -271,3 +271,14 @@ def patch(self, url, **kwargs):
271271

272272
def delete(self, url, **kwargs):
273273
return self._request('DELETE', url, **kwargs)
274+
275+
276+
def _close_after_stream(response, chunk_size):
277+
"""Iterate over the content and ensure the response is closed after."""
278+
# Yield each chunk in the response body
279+
for chunk in response.iter_content(chunk_size=chunk_size):
280+
yield chunk
281+
# Once we're done streaming the body, ensure everything is closed.
282+
# This will return the connection to the HTTPConnectionPool in urllib3
283+
# and ideally reduce the number of HTTPConnectionPool full warnings.
284+
response.close()

tests/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ def ok(self):
126126
def read(self, amt):
127127
return self.body.read(amt)
128128

129+
def close(self):
130+
pass
131+
129132
@property
130133
def content(self):
131134
if hasattr(self.body, "read"):

0 commit comments

Comments
 (0)