From d6af42b6b6d54713f09c3e1e983435bf2c3fa07d Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Tue, 19 Feb 2019 13:53:07 -0800 Subject: [PATCH] Clean up how we walk through ranges in ECAppIter Besides being easier to reason about, this also lets us run more unit tests under py37 which complains about a a generator raising StopIteration Change-Id: Ia6b945afef51bcc8ed20a7069fc60d5b8f9c9c0b --- swift/proxy/controllers/obj.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py index 0ad5dcdeb7..2e7e1493e4 100644 --- a/swift/proxy/controllers/obj.py +++ b/swift/proxy/controllers/obj.py @@ -25,6 +25,7 @@ # collected. We've seen objects hang around forever otherwise. from six.moves.urllib.parse import unquote +from six.moves import zip import collections import itertools @@ -1112,18 +1113,14 @@ class ECAppIter(object): resp.content_type = self.learned_content_type resp.content_length = self.obj_length - def _next_range(self): + def _next_ranges(self): # Each FA part should have approximately the same headers. We really # only care about Content-Range and Content-Type, and that'll be the # same for all the different FAs. - frag_iters = [] - headers = None - for parts_iter in self.internal_parts_iters: - part_info = next(parts_iter) - frag_iters.append(part_info['part_iter']) - headers = part_info['headers'] - headers = HeaderKeyDict(headers) - return headers, frag_iters + for part_infos in zip(*self.internal_parts_iters): + frag_iters = [pi['part_iter'] for pi in part_infos] + headers = HeaderKeyDict(part_infos[0]['headers']) + yield headers, frag_iters def _actual_range(self, req_start, req_end, entity_length): # Takes 3 args: (requested-first-byte, requested-last-byte, @@ -1272,11 +1269,7 @@ class ECAppIter(object): seen_first_headers = False ranges_for_resp = {} - while True: - # this'll raise StopIteration and exit the loop - next_range = self._next_range() - - headers, frag_iters = next_range + for headers, frag_iters in self._next_ranges(): content_type = headers['Content-Type'] content_range = headers.get('Content-Range')