Don't fail response if caching failed
Fixes bug 929762 Change-Id: I90761b69cc556b14fd4bdb931541804244b653e8
This commit is contained in:
parent
e4db87ce4c
commit
481929b5c5
1
Authors
1
Authors
@ -28,6 +28,7 @@ Kevin L. Mitchell <kevin.mitchell@rackspace.com>
|
||||
Lorin Hochstein <lorin@isi.edu>
|
||||
Major Hayden <major@mhtx.net>
|
||||
Mark McLoughlin <markmc@redhat.com>
|
||||
Mark Washenberger <mark.washenberger@rackspace.com>
|
||||
Matt Dietz <matt.dietz@rackspace.com>
|
||||
Mike Lundy <mike@pistoncloud.com>
|
||||
Monty Taylor <mordred@inaugust.com>
|
||||
|
@ -220,11 +220,22 @@ class ImageCache(object):
|
||||
logger.debug(_("Tee'ing image '%s' into cache"), image_id)
|
||||
|
||||
def tee_iter(image_id):
|
||||
with self.driver.open_for_write(image_id) as cache_file:
|
||||
for chunk in image_iter:
|
||||
cache_file.write(chunk)
|
||||
yield chunk
|
||||
cache_file.flush()
|
||||
try:
|
||||
with self.driver.open_for_write(image_id) as cache_file:
|
||||
for chunk in image_iter:
|
||||
try:
|
||||
cache_file.write(chunk)
|
||||
finally:
|
||||
yield chunk
|
||||
cache_file.flush()
|
||||
except Exception:
|
||||
logger.exception(_("Exception encountered while tee'ing "
|
||||
"image '%s' into cache. Continuing "
|
||||
"with response.") % image_id)
|
||||
|
||||
# NOTE(markwash): continue responding even if caching failed
|
||||
for chunk in image_iter:
|
||||
yield chunk
|
||||
|
||||
return tee_iter(image_id)
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from contextlib import contextmanager
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
@ -24,6 +25,7 @@ import unittest
|
||||
import stubout
|
||||
|
||||
from glance import image_cache
|
||||
from glance.common import cfg
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance.tests import utils as test_utils
|
||||
@ -308,3 +310,62 @@ class TestImageCacheSqlite(unittest.TestCase,
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.cache_dir):
|
||||
shutil.rmtree(self.cache_dir)
|
||||
|
||||
|
||||
class TestImageCacheNoDep(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.driver = None
|
||||
|
||||
def init_driver(self2):
|
||||
self2.driver = self.driver
|
||||
|
||||
self.stubs = stubout.StubOutForTesting()
|
||||
self.stubs.Set(image_cache.ImageCache, 'init_driver', init_driver)
|
||||
|
||||
def tearDown(self):
|
||||
self.stubs.UnsetAll()
|
||||
|
||||
def test_get_caching_iter_when_write_fails(self):
|
||||
|
||||
class FailingFile(object):
|
||||
|
||||
def write(self, data):
|
||||
if data == "Fail":
|
||||
raise IOError
|
||||
|
||||
class FailingFileDriver(object):
|
||||
|
||||
def is_cacheable(self, *args, **kwargs):
|
||||
return True
|
||||
|
||||
@contextmanager
|
||||
def open_for_write(self, *args, **kwargs):
|
||||
yield FailingFile()
|
||||
|
||||
self.driver = FailingFileDriver()
|
||||
conf = cfg.ConfigOpts()
|
||||
cache = image_cache.ImageCache(conf)
|
||||
data = ['a', 'b', 'c', 'Fail', 'd', 'e', 'f']
|
||||
|
||||
caching_iter = cache.get_caching_iter('dummy_id', iter(data))
|
||||
self.assertEqual(list(caching_iter), data)
|
||||
|
||||
def test_get_caching_iter_when_open_fails(self):
|
||||
|
||||
class OpenFailingDriver(object):
|
||||
|
||||
def is_cacheable(self, *args, **kwargs):
|
||||
return True
|
||||
|
||||
@contextmanager
|
||||
def open_for_write(self, *args, **kwargs):
|
||||
raise IOError
|
||||
|
||||
self.driver = OpenFailingDriver()
|
||||
conf = cfg.ConfigOpts()
|
||||
cache = image_cache.ImageCache(conf)
|
||||
data = ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
|
||||
caching_iter = cache.get_caching_iter('dummy_id', iter(data))
|
||||
self.assertEqual(list(caching_iter), data)
|
||||
|
Loading…
Reference in New Issue
Block a user