Merge "Cache is_bfv check in ResourceTracker"

This commit is contained in:
Zuul 2018-08-01 17:09:07 +00:00 committed by Gerrit Code Review
commit 298de58b32
2 changed files with 33 additions and 4 deletions

View File

@ -140,6 +140,7 @@ class ResourceTracker(object):
self.stats = stats.Stats()
self.tracked_instances = {}
self.tracked_migrations = {}
self.is_bfv = {} # dict, keyed by instance uuid, to is_bfv boolean
monitor_handler = monitors.MonitorHandler(self)
self.monitors = monitor_handler.monitors
self.old_resources = collections.defaultdict(objects.ComputeNode)
@ -1142,6 +1143,12 @@ class ResourceTracker(object):
self._update_usage(self._get_usage_dict(instance), nodename,
sign=sign)
# Stop tracking removed instances in the is_bfv cache. This needs to
# happen *after* calling _get_usage_dict() since that relies on the
# is_bfv cache.
if is_removed_instance and uuid in self.is_bfv:
del self.is_bfv[uuid]
cn.current_workload = self.stats.calculate_workload()
if self.pci_tracker:
obj = self.pci_tracker.stats.to_device_pools_obj()
@ -1459,8 +1466,13 @@ class ResourceTracker(object):
"""
usage = {}
if isinstance(object_or_dict, objects.Instance):
is_bfv = compute_utils.is_volume_backed_instance(
object_or_dict._context, object_or_dict)
# Check to see if we have the is_bfv value cached.
if object_or_dict.uuid in self.is_bfv:
is_bfv = self.is_bfv[object_or_dict.uuid]
else:
is_bfv = compute_utils.is_volume_backed_instance(
object_or_dict._context, object_or_dict)
self.is_bfv[object_or_dict.uuid] = is_bfv
usage = {'memory_mb': object_or_dict.flavor.memory_mb,
'swap': object_or_dict.flavor.swap,
'vcpus': object_or_dict.flavor.vcpus,

View File

@ -2680,9 +2680,22 @@ class TestUpdateUsageFromInstance(BaseTestCase):
@mock.patch('nova.compute.utils.is_volume_backed_instance')
def test_get_usage_dict_return_0_root_gb_for_bfv_instance(
self, mock_check_bfv):
mock_check_bfv.retur_value = True
mock_check_bfv.return_value = True
# Make sure the cache is empty.
self.assertNotIn(self.instance.uuid, self.rt.is_bfv)
result = self.rt._get_usage_dict(self.instance)
self.assertEqual(0, result['root_gb'])
mock_check_bfv.assert_called_once_with(
self.instance._context, self.instance)
# Make sure we updated the cache.
self.assertIn(self.instance.uuid, self.rt.is_bfv)
self.assertTrue(self.rt.is_bfv[self.instance.uuid])
# Now run _get_usage_dict again to make sure we don't call
# is_volume_backed_instance.
mock_check_bfv.reset_mock()
result = self.rt._get_usage_dict(self.instance)
self.assertEqual(0, result['root_gb'])
mock_check_bfv.assert_not_called()
@mock.patch('nova.compute.utils.is_volume_backed_instance')
def test_get_usage_dict_include_swap(
@ -2711,12 +2724,16 @@ class TestUpdateUsageFromInstance(BaseTestCase):
def test_shelve_offloading(self, mock_update_usage, mock_check_bfv):
mock_check_bfv.return_value = False
self.instance.vm_state = vm_states.SHELVED_OFFLOADED
# Stub out the is_bfv cache to make sure we remove the instance
# from it after updating usage.
self.rt.is_bfv[self.instance.uuid] = False
self.rt.tracked_instances = {
self.instance.uuid: obj_base.obj_to_primitive(self.instance)
}
self.rt._update_usage_from_instance(mock.sentinel.ctx, self.instance,
_NODENAME)
# The instance should have been removed from the is_bfv cache.
self.assertNotIn(self.instance.uuid, self.rt.is_bfv)
mock_update_usage.assert_called_once_with(
self.rt._get_usage_dict(self.instance), _NODENAME, sign=-1)