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>
|
Lorin Hochstein <lorin@isi.edu>
|
||||||
Major Hayden <major@mhtx.net>
|
Major Hayden <major@mhtx.net>
|
||||||
Mark McLoughlin <markmc@redhat.com>
|
Mark McLoughlin <markmc@redhat.com>
|
||||||
|
Mark Washenberger <mark.washenberger@rackspace.com>
|
||||||
Matt Dietz <matt.dietz@rackspace.com>
|
Matt Dietz <matt.dietz@rackspace.com>
|
||||||
Mike Lundy <mike@pistoncloud.com>
|
Mike Lundy <mike@pistoncloud.com>
|
||||||
Monty Taylor <mordred@inaugust.com>
|
Monty Taylor <mordred@inaugust.com>
|
||||||
|
@ -220,11 +220,22 @@ class ImageCache(object):
|
|||||||
logger.debug(_("Tee'ing image '%s' into cache"), image_id)
|
logger.debug(_("Tee'ing image '%s' into cache"), image_id)
|
||||||
|
|
||||||
def tee_iter(image_id):
|
def tee_iter(image_id):
|
||||||
with self.driver.open_for_write(image_id) as cache_file:
|
try:
|
||||||
for chunk in image_iter:
|
with self.driver.open_for_write(image_id) as cache_file:
|
||||||
cache_file.write(chunk)
|
for chunk in image_iter:
|
||||||
yield chunk
|
try:
|
||||||
cache_file.flush()
|
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)
|
return tee_iter(image_id)
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
@ -24,6 +25,7 @@ import unittest
|
|||||||
import stubout
|
import stubout
|
||||||
|
|
||||||
from glance import image_cache
|
from glance import image_cache
|
||||||
|
from glance.common import cfg
|
||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
from glance.common import utils
|
from glance.common import utils
|
||||||
from glance.tests import utils as test_utils
|
from glance.tests import utils as test_utils
|
||||||
@ -308,3 +310,62 @@ class TestImageCacheSqlite(unittest.TestCase,
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if os.path.exists(self.cache_dir):
|
if os.path.exists(self.cache_dir):
|
||||||
shutil.rmtree(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