Defer segment lookup in NetworkContext object

Avoid call to get network segments for network context objects until
a caller actually tries to lookup the segments. This optimizes cases
where the user of a port context never looks at the segments of the
associated network context (e.g. update_port_status).

Closes-Bug: #1463254
Change-Id: I7e95f81d9a3ef26ccdb18c6bfdf9adc29523aa79
This commit is contained in:
Kevin Benton 2015-06-03 19:03:29 -07:00 committed by Kevin Benton
parent e95510f8d1
commit e61865807c
2 changed files with 51 additions and 25 deletions

View File

@ -42,8 +42,8 @@ class NetworkContext(MechanismDriverContext, api.NetworkContext):
super(NetworkContext, self).__init__(plugin, plugin_context)
self._network = network
self._original_network = original_network
self._segments = db.get_network_segments(plugin_context.session,
network['id'])
self._segments = None
self._session = plugin_context.session
@property
def current(self):
@ -55,6 +55,9 @@ class NetworkContext(MechanismDriverContext, api.NetworkContext):
@property
def network_segments(self):
if not self._segments:
self._segments = db.get_network_segments(self._session,
self._network['id'])
return self._segments

View File

@ -37,13 +37,12 @@ class TestPortContext(base.BaseTestCase):
port = {'device_owner': constants.DEVICE_OWNER_DVR_INTERFACE}
binding.host = 'foohost'
with mock.patch.object(driver_context.db, 'get_network_segments'):
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
self.assertEqual('foohost', ctx.host)
def test_host_super(self):
@ -56,13 +55,12 @@ class TestPortContext(base.BaseTestCase):
portbindings.HOST_ID: 'host'}
binding.host = 'foohost'
with mock.patch.object(driver_context.db, 'get_network_segments'):
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
self.assertEqual('host', ctx.host)
def test_status(self):
@ -74,13 +72,12 @@ class TestPortContext(base.BaseTestCase):
port = {'device_owner': constants.DEVICE_OWNER_DVR_INTERFACE}
binding.status = 'foostatus'
with mock.patch.object(driver_context.db, 'get_network_segments'):
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
self.assertEqual('foostatus', ctx.status)
def test_status_super(self):
@ -93,11 +90,37 @@ class TestPortContext(base.BaseTestCase):
'status': 'status'}
binding.status = 'foostatus'
with mock.patch.object(driver_context.db, 'get_network_segments'):
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
self.assertEqual('status', ctx.status)
def test_segments_lazy_lookup(self):
plugin = mock.Mock()
plugin_context = mock.Mock()
network = mock.MagicMock()
binding = mock.Mock()
port = {'device_owner': 'compute',
'status': 'status'}
binding.status = 'foostatus'
with mock.patch.object(driver_context.db,
'get_network_segments') as gs:
ctx = driver_context.PortContext(plugin,
plugin_context,
port,
network,
binding,
None)
self.assertEqual('status', ctx.status)
self.assertFalse(gs.called)
# accessing the network_segments property should trigger
# a lookup the first time
seg = ctx.network.network_segments
self.assertTrue(gs.called)
gs.reset_mock()
self.assertEqual(seg, ctx.network.network_segments)
self.assertFalse(gs.called)