Add caching of service_min_versions in the conductor
Since we may need this information in the conductor a lot, as it has to be used to determine whether data migration can be done, we cache the results. The cache gets cleared on SIGHUP, so any update of a service would require a SIGHUP to the conductors Now (similar to how it's done for the compute task service). We enable this caching only for the conductor nodes as it is not needed elsewhere. Change-Id: I79e2f0e79e17141052e7a8128e0d64975e0b4b5f
This commit is contained in:
parent
f1da349a4f
commit
5b13f1d0c5
|
@ -36,6 +36,7 @@ def main():
|
|||
logging.setup(CONF, "nova")
|
||||
utils.monkey_patch()
|
||||
objects.register_all()
|
||||
objects.Service.enable_min_version_cache()
|
||||
|
||||
gmr.TextGuruMeditation.setup_autorun(version)
|
||||
|
||||
|
|
|
@ -131,6 +131,9 @@ class ConductorManager(manager.Manager):
|
|||
return objinst.obj_to_primitive(target_version=target,
|
||||
version_manifest=object_versions)
|
||||
|
||||
def reset(self):
|
||||
objects.Service.clear_min_version_cache()
|
||||
|
||||
|
||||
class ComputeTaskManager(base.Base):
|
||||
"""Namespace for compute methods.
|
||||
|
|
|
@ -102,6 +102,9 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
|||
'version': fields.IntegerField(),
|
||||
}
|
||||
|
||||
_MIN_VERSION_CACHE = {}
|
||||
_SERVICE_VERSION_CACHING = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# NOTE(danms): We're going against the rules here and overriding
|
||||
# init. The reason is that we want to *ensure* that we're always
|
||||
|
@ -279,6 +282,15 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
|||
def destroy(self):
|
||||
db.service_destroy(self._context, self.id)
|
||||
|
||||
@classmethod
|
||||
def enable_min_version_cache(cls):
|
||||
cls.clear_min_version_cache()
|
||||
cls._SERVICE_VERSION_CACHING = True
|
||||
|
||||
@classmethod
|
||||
def clear_min_version_cache(cls):
|
||||
cls._MIN_VERSION_CACHE = {}
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_minimum_version(cls, context, binary, use_slave=False):
|
||||
if not binary.startswith('nova-'):
|
||||
|
@ -286,13 +298,21 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
|||
'binary `%s\''), binary)
|
||||
raise exception.ObjectActionError(action='get_minimum_version',
|
||||
reason='Invalid binary prefix')
|
||||
|
||||
if cls._SERVICE_VERSION_CACHING:
|
||||
cached_version = cls._MIN_VERSION_CACHE.get(binary)
|
||||
if cached_version:
|
||||
return cached_version
|
||||
version = db.service_get_minimum_version(context, binary,
|
||||
use_slave=use_slave)
|
||||
if version is None:
|
||||
return 0
|
||||
# NOTE(danms): Since our return value is not controlled by object
|
||||
# schema, be explicit here.
|
||||
return int(version)
|
||||
version = int(version)
|
||||
cls._MIN_VERSION_CACHE[binary] = version
|
||||
|
||||
return version
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
|
|
|
@ -189,6 +189,12 @@ class ConductorTestCase(_BaseTestCase, test.TestCase):
|
|||
m.return_value.obj_to_primitive.assert_called_once_with(
|
||||
target_version='1.2', version_manifest=versions)
|
||||
|
||||
def test_reset(self):
|
||||
with mock.patch.object(objects.Service, 'clear_min_version_cache'
|
||||
) as mock_clear_cache:
|
||||
self.conductor.reset()
|
||||
mock_clear_cache.assert_called_once_with()
|
||||
|
||||
|
||||
class ConductorRPCAPITestCase(_BaseTestCase, test.TestCase):
|
||||
"""Conductor RPC API Tests."""
|
||||
|
|
|
@ -296,6 +296,23 @@ class _TestServiceObject(object):
|
|||
'compute')
|
||||
self.assertTrue(mock_log.warning.called)
|
||||
|
||||
@mock.patch('nova.db.service_get_minimum_version')
|
||||
def test_get_minimum_version_with_caching(self, mock_get):
|
||||
objects.Service.enable_min_version_cache()
|
||||
mock_get.return_value = 123
|
||||
self.assertEqual(123,
|
||||
objects.Service.get_minimum_version(self.context,
|
||||
'nova-compute'))
|
||||
self.assertEqual({"nova-compute": 123},
|
||||
objects.Service._MIN_VERSION_CACHE)
|
||||
self.assertEqual(123,
|
||||
objects.Service.get_minimum_version(self.context,
|
||||
'nova-compute'))
|
||||
mock_get.assert_called_once_with(self.context, 'nova-compute',
|
||||
use_slave=False)
|
||||
objects.Service._SERVICE_VERSION_CACHING = False
|
||||
objects.Service.clear_min_version_cache()
|
||||
|
||||
@mock.patch('nova.db.service_get_minimum_version', return_value=2)
|
||||
def test_create_above_minimum(self, mock_get):
|
||||
with mock.patch('nova.objects.service.SERVICE_VERSION',
|
||||
|
|
Loading…
Reference in New Issue