Merge "Dynamic Large Object sleeps too much"
This commit is contained in:
commit
01a5a47610
@ -111,7 +111,7 @@ class SegmentedIterable(object):
|
|||||||
self.container = container
|
self.container = container
|
||||||
self.listing = segment_listing_iter(listing)
|
self.listing = segment_listing_iter(listing)
|
||||||
self.is_slo = is_slo
|
self.is_slo = is_slo
|
||||||
self.segment = 0
|
self.ratelimit_index = 0
|
||||||
self.segment_dict = None
|
self.segment_dict = None
|
||||||
self.segment_peek = None
|
self.segment_peek = None
|
||||||
self.seek = 0
|
self.seek = 0
|
||||||
@ -132,7 +132,7 @@ class SegmentedIterable(object):
|
|||||||
segment no longer matches SLO manifest specifications.
|
segment no longer matches SLO manifest specifications.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.segment += 1
|
self.ratelimit_index += 1
|
||||||
self.segment_dict = self.segment_peek or self.listing.next()
|
self.segment_dict = self.segment_peek or self.listing.next()
|
||||||
self.segment_peek = None
|
self.segment_peek = None
|
||||||
if self.container is None:
|
if self.container is None:
|
||||||
@ -147,7 +147,7 @@ class SegmentedIterable(object):
|
|||||||
if self.seek:
|
if self.seek:
|
||||||
req.range = 'bytes=%s-' % self.seek
|
req.range = 'bytes=%s-' % self.seek
|
||||||
self.seek = 0
|
self.seek = 0
|
||||||
if not self.is_slo and self.segment > \
|
if not self.is_slo and self.ratelimit_index > \
|
||||||
self.controller.app.rate_limit_after_segment:
|
self.controller.app.rate_limit_after_segment:
|
||||||
sleep(max(self.next_get_time - time.time(), 0))
|
sleep(max(self.next_get_time - time.time(), 0))
|
||||||
self.next_get_time = time.time() + \
|
self.next_get_time = time.time() + \
|
||||||
@ -246,7 +246,6 @@ class SegmentedIterable(object):
|
|||||||
if start:
|
if start:
|
||||||
self.segment_peek = self.listing.next()
|
self.segment_peek = self.listing.next()
|
||||||
while start >= self.position + self.segment_peek['bytes']:
|
while start >= self.position + self.segment_peek['bytes']:
|
||||||
self.segment += 1
|
|
||||||
self.position += self.segment_peek['bytes']
|
self.position += self.segment_peek['bytes']
|
||||||
self.segment_peek = self.listing.next()
|
self.segment_peek = self.listing.next()
|
||||||
self.seek = start - self.position
|
self.seek = start - self.position
|
||||||
|
@ -5466,10 +5466,51 @@ class TestSegmentedIterable(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
swift.proxy.controllers.obj.sleep = orig_sleep
|
swift.proxy.controllers.obj.sleep = orig_sleep
|
||||||
|
|
||||||
|
def test_load_next_segment_range_req_rate_limiting(self):
|
||||||
|
sleep_calls = []
|
||||||
|
|
||||||
|
def _stub_sleep(sleepy_time):
|
||||||
|
sleep_calls.append(sleepy_time)
|
||||||
|
orig_sleep = swift.proxy.controllers.obj.sleep
|
||||||
|
try:
|
||||||
|
swift.proxy.controllers.obj.sleep = _stub_sleep
|
||||||
|
segit = SegmentedIterable(
|
||||||
|
self.controller, 'lc', [
|
||||||
|
{'name': 'o0', 'bytes': 5}, {'name': 'o1', 'bytes': 5},
|
||||||
|
{'name': 'o2', 'bytes': 1}, {'name': 'o3'}, {'name': 'o4'},
|
||||||
|
{'name': 'o5'}, {'name': 'o6'}])
|
||||||
|
|
||||||
|
# this tests for a range request which skips over the whole first
|
||||||
|
# segment, after that 3 segments will be read in because the
|
||||||
|
# rate_limit_after_segment == 3, then sleeping starts
|
||||||
|
segit_iter = segit.app_iter_range(10, None)
|
||||||
|
segit_iter.next()
|
||||||
|
for _ in xrange(2):
|
||||||
|
# this is set to 2 instead of 3 because o2 was loaded after
|
||||||
|
# o0 and o1 were skipped.
|
||||||
|
segit._load_next_segment()
|
||||||
|
self.assertEquals([], sleep_calls)
|
||||||
|
self.assertEquals(self.controller.GETorHEAD_base_args[4],
|
||||||
|
'/a/lc/o4')
|
||||||
|
|
||||||
|
# Loading of next (5th) segment starts rate-limiting.
|
||||||
|
segit._load_next_segment()
|
||||||
|
self.assertAlmostEqual(0.5, sleep_calls[0], places=2)
|
||||||
|
self.assertEquals(self.controller.GETorHEAD_base_args[4],
|
||||||
|
'/a/lc/o5')
|
||||||
|
|
||||||
|
sleep_calls = []
|
||||||
|
segit._load_next_segment()
|
||||||
|
self.assertAlmostEqual(0.5, sleep_calls[0], places=2)
|
||||||
|
self.assertEquals(self.controller.GETorHEAD_base_args[4],
|
||||||
|
'/a/lc/o6')
|
||||||
|
finally:
|
||||||
|
swift.proxy.controllers.obj.sleep = orig_sleep
|
||||||
|
|
||||||
def test_load_next_segment_with_two_segments_skip_first(self):
|
def test_load_next_segment_with_two_segments_skip_first(self):
|
||||||
segit = SegmentedIterable(self.controller, 'lc', [{'name':
|
segit = SegmentedIterable(self.controller, 'lc', [{'name':
|
||||||
'o1'}, {'name': 'o2'}])
|
'o1'}, {'name': 'o2'}])
|
||||||
segit.segment = 0
|
segit.ratelimit_index = 0
|
||||||
segit.listing.next()
|
segit.listing.next()
|
||||||
segit._load_next_segment()
|
segit._load_next_segment()
|
||||||
self.assertEquals(self.controller.GETorHEAD_base_args[4], '/a/lc/o2')
|
self.assertEquals(self.controller.GETorHEAD_base_args[4], '/a/lc/o2')
|
||||||
@ -5479,7 +5520,7 @@ class TestSegmentedIterable(unittest.TestCase):
|
|||||||
def test_load_next_segment_with_seek(self):
|
def test_load_next_segment_with_seek(self):
|
||||||
segit = SegmentedIterable(self.controller, 'lc', [{'name':
|
segit = SegmentedIterable(self.controller, 'lc', [{'name':
|
||||||
'o1'}, {'name': 'o2'}])
|
'o1'}, {'name': 'o2'}])
|
||||||
segit.segment = 0
|
segit.ratelimit_index = 0
|
||||||
segit.listing.next()
|
segit.listing.next()
|
||||||
segit.seek = 1
|
segit.seek = 1
|
||||||
segit._load_next_segment()
|
segit._load_next_segment()
|
||||||
|
Loading…
Reference in New Issue
Block a user