Skip to content

Commit

Permalink
Make cooperative reader always support read()
Browse files Browse the repository at this point in the history
glance.common.utils.CooperativeReader provides eventlet-friendly
cooperation on top of backends that support either read() or __iter__().
However, in the case of backends that only support __iter__(), such as
images returned by store.get(...), read() is not defined. This patch
adds read() in all cases.

Fixes bug 1057322.

Change-Id: I67d9b3e4d93fbefd7eeaf7cfc947ab635fe09534
  • Loading branch information
markwash committed Nov 20, 2012
1 parent a386310 commit 5daed10
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
17 changes: 17 additions & 0 deletions glance/common/utils.py
Expand Up @@ -116,9 +116,26 @@ def __init__(self, fd):
:param fd: Underlying image file object
"""
self.fd = fd
self.iterator = None
# NOTE(markwash): if the underlying supports read(), overwrite the
# default iterator-based implementation with cooperative_read which
# is more straightforward
if hasattr(fd, 'read'):
self.read = cooperative_read(fd)

def read(self, length=None):
"""Return the next chunk of the underlying iterator.
This is replaced with cooperative_read in __init__ if the underlying
fd already supports read().
"""
if self.iterator is None:
self.iterator = self.__iter__()
try:
return self.iterator.next()
except StopIteration:
return ''

def __iter__(self):
return cooperative_iter(self.fd.__iter__())

Expand Down
11 changes: 11 additions & 0 deletions glance/tests/unit/test_utils.py
Expand Up @@ -50,6 +50,17 @@ def test_cooperative_reader(self):

self.assertEquals(bytes_read, BYTES)

def test_cooperative_reader_of_iterator(self):
"""Ensure cooperative reader supports iterator backends too"""
reader = utils.CooperativeReader([l * 3 for l in 'abcdefgh'])
chunks = []
while True:
chunks.append(reader.read(3))
if chunks[-1] == '':
break
meat = ''.join(chunks)
self.assertEqual(meat, 'aaabbbcccdddeeefffggghhh')

def test_limiting_reader(self):
"""Ensure limiting reader class accesses all bytes of file"""
BYTES = 1024
Expand Down

0 comments on commit 5daed10

Please sign in to comment.