From d7cc83129966109556df8669aa970ff39fd156ed Mon Sep 17 00:00:00 2001 From: Jim Rollenhagen Date: Tue, 7 Oct 2014 16:24:31 -0700 Subject: [PATCH] Clear hash ring cache in get_topic_for* This causes the hash ring to be reset on each API request, avoiding an issue where a new conductor never joins the ring until the API service is restarted. Closes-Bug: 1378570 Change-Id: Ic57370163f2f833efab662837036298f29f4ca90 --- ironic/conductor/rpcapi.py | 4 ++++ ironic/tests/conductor/test_rpcapi.py | 31 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ironic/conductor/rpcapi.py b/ironic/conductor/rpcapi.py index 4fa96f1aab..452fc0ceeb 100644 --- a/ironic/conductor/rpcapi.py +++ b/ironic/conductor/rpcapi.py @@ -87,6 +87,8 @@ class ConductorAPI(object): :raises: NoValidHost """ + self.ring_manager.reset() + try: ring = self.ring_manager[node.driver] dest = ring.get_hosts(node.uuid) @@ -106,6 +108,8 @@ class ConductorAPI(object): :raises: DriverNotFound """ + self.ring_manager.reset() + hash_ring = self.ring_manager[driver_name] host = random.choice(list(hash_ring.hosts)) return self.topic + "." + host diff --git a/ironic/tests/conductor/test_rpcapi.py b/ironic/tests/conductor/test_rpcapi.py index 2715649d6b..47a938c476 100644 --- a/ironic/tests/conductor/test_rpcapi.py +++ b/ironic/tests/conductor/test_rpcapi.py @@ -78,6 +78,22 @@ class RPCAPITestCase(base.DbTestCase): rpcapi.get_topic_for, self.fake_node_obj) + def test_get_topic_doesnt_cache(self): + CONF.set_override('host', 'fake-host') + + rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic') + self.assertRaises(exception.NoValidHost, + rpcapi.get_topic_for, + self.fake_node_obj) + + self.dbapi.register_conductor({'hostname': 'fake-host', + 'drivers': ['fake-driver']}) + + rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic') + expected_topic = 'fake-topic.fake-host' + self.assertEqual(expected_topic, + rpcapi.get_topic_for(self.fake_node_obj)) + def test_get_topic_for_driver_known_driver(self): CONF.set_override('host', 'fake-host') self.dbapi.register_conductor({ @@ -99,6 +115,21 @@ class RPCAPITestCase(base.DbTestCase): rpcapi.get_topic_for_driver, 'fake-driver') + def test_get_topic_for_driver_doesnt_cache(self): + CONF.set_override('host', 'fake-host') + rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic') + self.assertRaises(exception.DriverNotFound, + rpcapi.get_topic_for_driver, + 'fake-driver') + + self.dbapi.register_conductor({ + 'hostname': 'fake-host', + 'drivers': ['fake-driver'], + }) + rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic') + self.assertEqual('fake-topic.fake-host', + rpcapi.get_topic_for_driver('fake-driver')) + def _test_rpcapi(self, method, rpc_method, **kwargs): rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic')