Minimize ovs l2 agent calls to get_vif_port_set()

The ovs l2 agent was previously calling get_vif_port_set() on the
integration bridge once per rpc_loop() iteration and then again in
the periodic _report_state() call that returns the current device
count to the neutron service.  Since get_vif_port_set() is an
expensive call (relying on shell commands) and since there
is minimal risk associated with reporting stats that are a few
seconds old, this patch caches the device count for reuse by
_report_state().

Partial-Bug: 1177973

Change-Id: Ice73384ed1ba1e97120028cd0a9bff94a62a41a4
This commit is contained in:
Maru Newby 2013-08-22 07:57:00 +00:00
parent 4be6b6e697
commit abcc687a26
2 changed files with 11 additions and 10 deletions

View File

@ -198,6 +198,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
'start_flag': True} 'start_flag': True}
self.setup_rpc() self.setup_rpc()
# Keep track of int_br's device count for use by _report_state()
self.int_br_device_count = 0
# Security group agent supprot # Security group agent supprot
self.sg_agent = OVSSecurityGroupAgent(self.context, self.sg_agent = OVSSecurityGroupAgent(self.context,
self.plugin_rpc, self.plugin_rpc,
@ -211,9 +214,8 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
def _report_state(self): def _report_state(self):
try: try:
# How many devices are likely used by a VM # How many devices are likely used by a VM
ports = self.int_br.get_vif_port_set() self.agent_state.get('configurations')['devices'] = (
num_devices = len(ports) self.int_br_device_count)
self.agent_state.get('configurations')['devices'] = num_devices
self.state_rpc.report_state(self.context, self.state_rpc.report_state(self.context,
self.agent_state) self.agent_state)
self.agent_state.pop('start_flag', None) self.agent_state.pop('start_flag', None)
@ -655,6 +657,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
ports = self.int_br.get_vif_port_set() ports = self.int_br.get_vif_port_set()
if ports == registered_ports: if ports == registered_ports:
return return
self.int_br_device_count = len(ports)
added = ports - registered_ports added = ports - registered_ports
removed = registered_ports - ports removed = registered_ports - ports
return {'current': ports, return {'current': ports,

View File

@ -222,18 +222,16 @@ class TestOvsNeutronAgent(base.BaseTestCase):
self.assertTrue(device_removed.called) self.assertTrue(device_removed.called)
def test_report_state(self): def test_report_state(self):
with contextlib.nested( with mock.patch.object(self.agent.state_rpc,
mock.patch.object(self.agent.int_br, "get_vif_port_set"), "report_state") as report_st:
mock.patch.object(self.agent.state_rpc, "report_state") self.agent.int_br_device_count = 5
) as (get_vif_fn, report_st):
get_vif_fn.return_value = ["vif123", "vif234"]
self.agent._report_state() self.agent._report_state()
self.assertTrue(get_vif_fn.called)
report_st.assert_called_with(self.agent.context, report_st.assert_called_with(self.agent.context,
self.agent.agent_state) self.agent.agent_state)
self.assertNotIn("start_flag", self.agent.agent_state) self.assertNotIn("start_flag", self.agent.agent_state)
self.assertEqual( self.assertEqual(
self.agent.agent_state["configurations"]["devices"], 2 self.agent.agent_state["configurations"]["devices"],
self.agent.int_br_device_count
) )
def test_network_delete(self): def test_network_delete(self):