From 752ceb266b3e72361242250e50396671df8b9595 Mon Sep 17 00:00:00 2001 From: Clay Gerrard Date: Fri, 2 Oct 2015 16:40:28 -0700 Subject: [PATCH] Close ECAppIter's sub-generators before propagating GeneratorExit ... which ensures no Timeouts remain pending after the parent generator is closed when a client disconnects before being able to read the entire body. Also tighten up a few tests that may have left some open ECAppIter generators lying about after the tests themselves had finished. This has the side effect of preventing the extraneous printing of the Timeout errors being raised by the eventlet hub in the background while our unittests are running. Change-Id: I156d873c72c19623bcfbf39bf120c98800b3cada --- swift/proxy/controllers/base.py | 6 +++++- test/unit/proxy/controllers/test_obj.py | 2 +- test/unit/proxy/test_server.py | 8 +++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index c852ae584b..3f4c79ab9b 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -917,6 +917,7 @@ class ResumingGetter(object): if nchunks % 5 == 0: sleep() + part_iter = None try: while True: start_byte, end_byte, length, headers, part = \ @@ -928,9 +929,12 @@ class ResumingGetter(object): 'entity_length': length, 'headers': headers, 'part_iter': part_iter} self.pop_range() + except GeneratorExit: + if part_iter: + part_iter.close() + raise except StopIteration: req.environ['swift.non_client_disconnect'] = True - return except ChunkReadTimeout: self.app.exception_occurred(node[0], _('Object'), diff --git a/test/unit/proxy/controllers/test_obj.py b/test/unit/proxy/controllers/test_obj.py index da3abd0c82..a41bb83b3f 100755 --- a/test/unit/proxy/controllers/test_obj.py +++ b/test/unit/proxy/controllers/test_obj.py @@ -2001,7 +2001,7 @@ class TestECObjController(BaseObjectControllerMixin, unittest.TestCase): try: resp.body except ECDriverError: - pass + resp._app_iter.close() else: self.fail('invalid ec fragment response body did not blow up!') error_lines = self.logger.get_lines_for_level('error') diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index 94613f6ea6..71c37d2cbf 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -5619,9 +5619,8 @@ class TestObjectController(unittest.TestCase): # read most of the object, and disconnect fd.read(10) - fd.close() - sock.close() - sleep(0) + sock.fd._sock.close() + sleep(0.1) # check for disconnect message! expected = ['Client disconnected on read'] * 2 @@ -5677,8 +5676,7 @@ class TestObjectController(unittest.TestCase): exp = 'HTTP/1.1 200' self.assertEqual(headers[:len(exp)], exp) fd.read(1) - fd.close() - sock.close() + sock.fd._sock.close() # Make sure the GC is run again for pythons without reference # counting for i in range(4):