summaryrefslogtreecommitdiff
path: root/ironic/nova
diff options
context:
space:
mode:
authorJim Rollenhagen <jim@jimrollenhagen.com>2014-08-08 22:08:50 +0000
committerJim Rollenhagen <jim@jimrollenhagen.com>2014-08-19 13:30:43 -0700
commitc05159c9c7201d926d423ce6ca5e0e679e8c60ad (patch)
treeb71084e4cd4263e23e8db52b637c177bcef9d063 /ironic/nova
parentd799a29a5a4f013aa457045dfeb6e91f9af611ff (diff)
downloadironic-c05159c9c7201d926d423ce6ca5e0e679e8c60ad.tar.gz
Use cache in node_is_available()
This should make start-up times much better. Closes-Bug: 1357027 Change-Id: I98ce118667dd9b8bf93ad781bfa8dc5077f34b45
Diffstat (limited to 'ironic/nova')
-rw-r--r--ironic/nova/tests/virt/ironic/test_driver.py30
-rw-r--r--ironic/nova/virt/ironic/driver.py14
2 files changed, 43 insertions, 1 deletions
diff --git a/ironic/nova/tests/virt/ironic/test_driver.py b/ironic/nova/tests/virt/ironic/test_driver.py
index 19b0b43d1..a9f4a25e2 100644
--- a/ironic/nova/tests/virt/ironic/test_driver.py
+++ b/ironic/nova/tests/virt/ironic/test_driver.py
@@ -290,16 +290,44 @@ class IronicDriverTestCase(test.NoDBTestCase):
expected = [n.instance_uuid for n in nodes]
self.assertEqual(sorted(expected), sorted(uuids))
+ @mock.patch.object(FAKE_CLIENT.node, 'list')
@mock.patch.object(FAKE_CLIENT.node, 'get')
- def test_node_is_available(self, mock_get):
+ def test_node_is_available_empty_cache_empty_list(self, mock_get,
+ mock_list):
node = ironic_utils.get_test_node()
mock_get.return_value = node
+ mock_list.return_value = []
self.assertTrue(self.driver.node_is_available(node.uuid))
mock_get.assert_called_with(node.uuid)
+ mock_list.assert_called_with(detail=True)
mock_get.side_effect = ironic_exception.NotFound
self.assertFalse(self.driver.node_is_available(node.uuid))
+ @mock.patch.object(FAKE_CLIENT.node, 'list')
+ @mock.patch.object(FAKE_CLIENT.node, 'get')
+ def test_node_is_available_empty_cache(self, mock_get, mock_list):
+ node = ironic_utils.get_test_node()
+ mock_get.return_value = node
+ mock_list.return_value = [node]
+ self.assertTrue(self.driver.node_is_available(node.uuid))
+ mock_list.assert_called_with(detail=True)
+ self.assertEqual(0, mock_get.call_count)
+
+ @mock.patch.object(FAKE_CLIENT.node, 'list')
+ @mock.patch.object(FAKE_CLIENT.node, 'get')
+ def test_node_is_available_with_cache(self, mock_get, mock_list):
+ node = ironic_utils.get_test_node()
+ mock_get.return_value = node
+ mock_list.return_value = [node]
+ # populate the cache
+ self.driver.get_available_nodes(refresh=True)
+ # prove that zero calls are made after populating cache
+ mock_list.reset_mock()
+ self.assertTrue(self.driver.node_is_available(node.uuid))
+ self.assertEqual(0, mock_list.call_count)
+ self.assertEqual(0, mock_get.call_count)
+
def test__node_resources_unavailable(self):
node_dicts = [
# a node in maintenance /w no instance and power OFF
diff --git a/ironic/nova/virt/ironic/driver.py b/ironic/nova/virt/ironic/driver.py
index c22d5c865..d26611c61 100644
--- a/ironic/nova/virt/ironic/driver.py
+++ b/ironic/nova/virt/ironic/driver.py
@@ -391,6 +391,20 @@ class IronicDriver(virt_driver.ComputeDriver):
:returns: True if the node exists, False if not.
"""
+ # NOTE(comstud): We can cheat and use caching here. This method
+ # just needs to return True for nodes that exist. It doesn't
+ # matter if the data is stale. Sure, it's possible that removing
+ # node from Ironic will cause this method to return True until
+ # the next call to 'get_available_nodes', but there shouldn't
+ # be much harm. There's already somewhat of a race.
+ if not self.node_cache:
+ # Empty cache, try to populate it.
+ self._refresh_cache()
+ if nodename in self.node_cache:
+ return True
+
+ # NOTE(comstud): Fallback and check Ironic. This case should be
+ # rare.
icli = client_wrapper.IronicClientWrapper()
try:
icli.call("node.get", nodename)