Merge "Windows OVS: minimize polling"
This commit is contained in:
commit
d6f6ddea38
|
@ -13,13 +13,63 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import contextlib
|
||||
|
||||
import eventlet
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.agent.common import async_process
|
||||
from neutron.agent.common import base_polling
|
||||
from neutron.agent.common import ovsdb_monitor
|
||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
if os.name == 'nt':
|
||||
from neutron.agent.windows import polling
|
||||
else:
|
||||
from neutron.agent.linux import polling
|
||||
@contextlib.contextmanager
|
||||
def get_polling_manager(minimize_polling=False,
|
||||
ovsdb_monitor_respawn_interval=(
|
||||
constants.DEFAULT_OVSDBMON_RESPAWN)):
|
||||
if minimize_polling:
|
||||
pm = InterfacePollingMinimizer(
|
||||
ovsdb_monitor_respawn_interval=ovsdb_monitor_respawn_interval)
|
||||
pm.start()
|
||||
else:
|
||||
pm = base_polling.AlwaysPoll()
|
||||
try:
|
||||
yield pm
|
||||
finally:
|
||||
if minimize_polling:
|
||||
pm.stop()
|
||||
|
||||
get_polling_manager = polling.get_polling_manager
|
||||
InterfacePollingMinimizer = polling.InterfacePollingMinimizer
|
||||
|
||||
class InterfacePollingMinimizer(base_polling.BasePollingManager):
|
||||
"""Monitors ovsdb to determine when polling is required."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ovsdb_monitor_respawn_interval=constants.DEFAULT_OVSDBMON_RESPAWN):
|
||||
|
||||
super(InterfacePollingMinimizer, self).__init__()
|
||||
self._monitor = ovsdb_monitor.SimpleInterfaceMonitor(
|
||||
respawn_interval=ovsdb_monitor_respawn_interval,
|
||||
ovsdb_connection=cfg.CONF.OVS.ovsdb_connection)
|
||||
|
||||
def start(self):
|
||||
self._monitor.start(block=True)
|
||||
|
||||
def stop(self):
|
||||
try:
|
||||
self._monitor.stop()
|
||||
except async_process.AsyncProcessException:
|
||||
LOG.debug("InterfacePollingMinimizer was not running when stopped")
|
||||
|
||||
def _is_polling_required(self):
|
||||
# Maximize the chances of update detection having a chance to
|
||||
# collect output.
|
||||
eventlet.sleep()
|
||||
return self._monitor.has_updates
|
||||
|
||||
def get_events(self):
|
||||
return self._monitor.get_events()
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
# Copyright 2013 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
|
||||
import eventlet
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.agent.common import async_process
|
||||
from neutron.agent.common import base_polling
|
||||
from neutron.agent.common import ovsdb_monitor
|
||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_polling_manager(minimize_polling=False,
|
||||
ovsdb_monitor_respawn_interval=(
|
||||
constants.DEFAULT_OVSDBMON_RESPAWN)):
|
||||
if minimize_polling:
|
||||
pm = InterfacePollingMinimizer(
|
||||
ovsdb_monitor_respawn_interval=ovsdb_monitor_respawn_interval)
|
||||
pm.start()
|
||||
else:
|
||||
pm = base_polling.AlwaysPoll()
|
||||
try:
|
||||
yield pm
|
||||
finally:
|
||||
if minimize_polling:
|
||||
pm.stop()
|
||||
|
||||
|
||||
class InterfacePollingMinimizer(base_polling.BasePollingManager):
|
||||
"""Monitors ovsdb to determine when polling is required."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ovsdb_monitor_respawn_interval=constants.DEFAULT_OVSDBMON_RESPAWN):
|
||||
|
||||
super(InterfacePollingMinimizer, self).__init__()
|
||||
self._monitor = ovsdb_monitor.SimpleInterfaceMonitor(
|
||||
respawn_interval=ovsdb_monitor_respawn_interval,
|
||||
ovsdb_connection=cfg.CONF.OVS.ovsdb_connection)
|
||||
|
||||
def start(self):
|
||||
self._monitor.start(block=True)
|
||||
|
||||
def stop(self):
|
||||
try:
|
||||
self._monitor.stop()
|
||||
except async_process.AsyncProcessException:
|
||||
LOG.debug("InterfacePollingMinimizer was not running when stopped")
|
||||
|
||||
def _is_polling_required(self):
|
||||
# Maximize the chances of update detection having a chance to
|
||||
# collect output.
|
||||
eventlet.sleep()
|
||||
return self._monitor.has_updates
|
||||
|
||||
def get_events(self):
|
||||
return self._monitor.get_events()
|
|
@ -1,30 +0,0 @@
|
|||
# Copyright 2015 Cloudbase Solutions.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import contextlib
|
||||
|
||||
from neutron.agent.common import base_polling
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_polling_manager(minimize_polling, ovsdb_monitor_respawn_interval):
|
||||
pm = base_polling.AlwaysPoll()
|
||||
yield pm
|
||||
|
||||
|
||||
# TODO(atuvenie): make this manager inherit from
|
||||
# that fully fledged polling manager interface
|
||||
class InterfacePollingMinimizer(object):
|
||||
pass
|
|
@ -24,9 +24,9 @@ from oslo_config import cfg
|
|||
from oslo_utils import uuidutils
|
||||
|
||||
from neutron.agent.common import ovs_lib
|
||||
from neutron.agent.common import polling
|
||||
from neutron.agent.l2 import l2_agent_extensions_manager as ext_manager
|
||||
from neutron.agent.linux import interface
|
||||
from neutron.agent.linux import polling
|
||||
from neutron.common import utils
|
||||
from neutron.conf.agent import common as agent_config
|
||||
from neutron.conf import common as common_config
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
import mock
|
||||
|
||||
from neutron.agent.common import base_polling as polling
|
||||
from neutron.agent.common import base_polling
|
||||
from neutron.agent.common import polling
|
||||
from neutron.agent.ovsdb.native import helpers
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
|
@ -22,7 +24,7 @@ class TestBasePollingManager(base.BaseTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(TestBasePollingManager, self).setUp()
|
||||
self.pm = polling.BasePollingManager()
|
||||
self.pm = base_polling.BasePollingManager()
|
||||
|
||||
def test__is_polling_required_should_not_be_implemented(self):
|
||||
self.assertRaises(NotImplementedError, self.pm._is_polling_required)
|
||||
|
@ -65,5 +67,56 @@ class TestBasePollingManager(base.BaseTestCase):
|
|||
class TestAlwaysPoll(base.BaseTestCase):
|
||||
|
||||
def test_is_polling_required_always_returns_true(self):
|
||||
pm = polling.AlwaysPoll()
|
||||
pm = base_polling.AlwaysPoll()
|
||||
self.assertTrue(pm.is_polling_required)
|
||||
|
||||
|
||||
class TestGetPollingManager(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetPollingManager, self).setUp()
|
||||
mock.patch.object(helpers, 'enable_connection_uri').start()
|
||||
|
||||
def test_return_always_poll_by_default(self):
|
||||
with polling.get_polling_manager() as pm:
|
||||
self.assertEqual(pm.__class__, base_polling.AlwaysPoll)
|
||||
|
||||
def test_manage_polling_minimizer(self):
|
||||
mock_target = 'neutron.agent.common.polling.InterfacePollingMinimizer'
|
||||
with mock.patch('%s.start' % mock_target) as mock_start:
|
||||
with mock.patch('%s.stop' % mock_target) as mock_stop:
|
||||
with polling.get_polling_manager(minimize_polling=True) as pm:
|
||||
self.assertEqual(pm.__class__,
|
||||
polling.InterfacePollingMinimizer)
|
||||
mock_stop.assert_has_calls([mock.call()])
|
||||
mock_start.assert_has_calls([mock.call()])
|
||||
|
||||
|
||||
class TestInterfacePollingMinimizer(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestInterfacePollingMinimizer, self).setUp()
|
||||
mock.patch.object(helpers, 'enable_connection_uri').start()
|
||||
self.pm = polling.InterfacePollingMinimizer()
|
||||
|
||||
def test_start_calls_monitor_start(self):
|
||||
with mock.patch.object(self.pm._monitor, 'start') as mock_start:
|
||||
self.pm.start()
|
||||
mock_start.assert_called_with(block=True)
|
||||
|
||||
def test_stop_calls_monitor_stop(self):
|
||||
with mock.patch.object(self.pm._monitor, 'stop') as mock_stop:
|
||||
self.pm.stop()
|
||||
mock_stop.assert_called_with()
|
||||
|
||||
def mock_has_updates(self, return_value):
|
||||
target = ('neutron.agent.common.ovsdb_monitor.SimpleInterfaceMonitor'
|
||||
'.has_updates')
|
||||
return mock.patch(
|
||||
target,
|
||||
new_callable=mock.PropertyMock(return_value=return_value),
|
||||
)
|
||||
|
||||
def test__is_polling_required_returns_when_updates_are_present(self):
|
||||
with self.mock_has_updates(True):
|
||||
self.assertTrue(self.pm._is_polling_required())
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
# Copyright 2013 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from neutron.agent.common import base_polling
|
||||
from neutron.agent.linux import polling
|
||||
from neutron.agent.ovsdb.native import helpers
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
class TestGetPollingManager(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetPollingManager, self).setUp()
|
||||
mock.patch.object(helpers, 'enable_connection_uri').start()
|
||||
|
||||
def test_return_always_poll_by_default(self):
|
||||
with polling.get_polling_manager() as pm:
|
||||
self.assertEqual(pm.__class__, base_polling.AlwaysPoll)
|
||||
|
||||
def test_manage_polling_minimizer(self):
|
||||
mock_target = 'neutron.agent.linux.polling.InterfacePollingMinimizer'
|
||||
with mock.patch('%s.start' % mock_target) as mock_start:
|
||||
with mock.patch('%s.stop' % mock_target) as mock_stop:
|
||||
with polling.get_polling_manager(minimize_polling=True) as pm:
|
||||
self.assertEqual(pm.__class__,
|
||||
polling.InterfacePollingMinimizer)
|
||||
mock_stop.assert_has_calls([mock.call()])
|
||||
mock_start.assert_has_calls([mock.call()])
|
||||
|
||||
|
||||
class TestInterfacePollingMinimizer(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestInterfacePollingMinimizer, self).setUp()
|
||||
mock.patch.object(helpers, 'enable_connection_uri').start()
|
||||
self.pm = polling.InterfacePollingMinimizer()
|
||||
|
||||
def test_start_calls_monitor_start(self):
|
||||
with mock.patch.object(self.pm._monitor, 'start') as mock_start:
|
||||
self.pm.start()
|
||||
mock_start.assert_called_with(block=True)
|
||||
|
||||
def test_stop_calls_monitor_stop(self):
|
||||
with mock.patch.object(self.pm._monitor, 'stop') as mock_stop:
|
||||
self.pm.stop()
|
||||
mock_stop.assert_called_with()
|
||||
|
||||
def mock_has_updates(self, return_value):
|
||||
target = ('neutron.agent.common.ovsdb_monitor.SimpleInterfaceMonitor'
|
||||
'.has_updates')
|
||||
return mock.patch(
|
||||
target,
|
||||
new_callable=mock.PropertyMock(return_value=return_value),
|
||||
)
|
||||
|
||||
def test__is_polling_required_returns_when_updates_are_present(self):
|
||||
with self.mock_has_updates(True):
|
||||
self.assertTrue(self.pm._is_polling_required())
|
Loading…
Reference in New Issue