Cache the automatic version pin to avoid repeated lookups
The compute rpcapi module was looking up the desired automatic version pin each time it was initialized. Turns out, we create and destroy this object too often, which means we do a lot of those lookups unnecessarily. That's a larger problem that will be harder to solve, but we can be smarter about the DB impact of that. This adds a cache of the last version we discovered and avoids doing the lookup when possible. It makes the reset() method invalidate the cache prior to reinitializing the object so that we will do the lookup on SIGHUP as desired. Closes-Bug: #1524444 Change-Id: Ia1c58efa7105d32973f6921c2144b17c30b764c2
This commit is contained in:
@@ -720,6 +720,7 @@ class ComputeManager(manager.Manager):
|
||||
|
||||
def reset(self):
|
||||
LOG.info(_LI('Reloading compute RPC API'))
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
||||
def _get_resource_tracker(self, nodename):
|
||||
|
@@ -47,6 +47,7 @@ rpcapi_cap_opt = cfg.StrOpt('compute',
|
||||
CONF.register_opt(rpcapi_cap_opt, 'upgrade_levels')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
LAST_VERSION = None
|
||||
|
||||
|
||||
def _compute_host(host, instance):
|
||||
@@ -333,6 +334,9 @@ class ComputeAPI(object):
|
||||
self.client = self.get_client(target, version_cap, serializer)
|
||||
|
||||
def _determine_version_cap(self, target):
|
||||
global LAST_VERSION
|
||||
if LAST_VERSION:
|
||||
return LAST_VERSION
|
||||
service_version = objects.Service.get_minimum_version(
|
||||
context.get_admin_context(), 'nova-compute')
|
||||
history = service_obj.SERVICE_VERSION_HISTORY
|
||||
@@ -350,6 +354,7 @@ class ComputeAPI(object):
|
||||
'service history for version %(version)i'),
|
||||
{'version': service_version})
|
||||
return target.version
|
||||
LAST_VERSION = version_cap
|
||||
LOG.info(_LI('Automatically selected compute RPC version %(rpc)s '
|
||||
'from minimum service version %(service)i'),
|
||||
{'rpc': version_cap,
|
||||
|
@@ -55,6 +55,7 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
def test_auto_pin(self, mock_get_min):
|
||||
mock_get_min.return_value = 1
|
||||
self.flags(compute='auto', group='upgrade_levels')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self.assertEqual('4.4', rpcapi.client.version_cap)
|
||||
mock_get_min.assert_called_once_with(mock.ANY, 'nova-compute')
|
||||
@@ -63,6 +64,7 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
def test_auto_pin_fails_if_too_old(self, mock_get_min):
|
||||
mock_get_min.return_value = 1955
|
||||
self.flags(compute='auto', group='upgrade_levels')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
self.assertRaises(exception.ServiceTooOld,
|
||||
compute_rpcapi.ComputeAPI)
|
||||
|
||||
@@ -70,10 +72,21 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
def test_auto_pin_kilo(self, mock_get_min):
|
||||
mock_get_min.return_value = 0
|
||||
self.flags(compute='auto', group='upgrade_levels')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self.assertEqual('4.0', rpcapi.client.version_cap)
|
||||
mock_get_min.assert_called_once_with(mock.ANY, 'nova-compute')
|
||||
|
||||
@mock.patch('nova.objects.Service.get_minimum_version')
|
||||
def test_auto_pin_caches(self, mock_get_min):
|
||||
mock_get_min.return_value = 1
|
||||
self.flags(compute='auto', group='upgrade_levels')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
compute_rpcapi.ComputeAPI()
|
||||
compute_rpcapi.ComputeAPI()
|
||||
mock_get_min.assert_called_once_with(mock.ANY, 'nova-compute')
|
||||
self.assertEqual('4.4', compute_rpcapi.LAST_VERSION)
|
||||
|
||||
def _test_compute_api(self, method, rpc_method,
|
||||
expected_args=None, **kwargs):
|
||||
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||
|
Reference in New Issue
Block a user