vmware-nsx/neutron/agent/linux/polling.py
Maru Newby 9d9fc01dd3 Add the option to minimize ovs l2 polling
This change adds the ability to monitor the local ovsdb for
interface changes so that the l2 agent can avoid unnecessary
polling.  Minimal changes are made to the agent so the risk
of breakage should be low.  Future efforts to make the agent
entirely event-based may be able to use OvsdbMonitor as a
starting point.

By default polling minimization is not done, and can only be
enabled by setting 'minimize_polling = True' in the ovs
section of the l2 agent's config file.

Closes-Bug: #1177973

Change-Id: I26c035b48a74df2148696869c5a9affae5ab3d27
2013-10-14 22:24:15 +00:00

105 lines
2.9 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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 neutron.agent.linux import ovsdb_monitor
@contextlib.contextmanager
def get_polling_manager(minimize_polling=False, root_helper=None):
if minimize_polling:
pm = InterfacePollingMinimizer(root_helper=root_helper)
pm.start()
else:
pm = AlwaysPoll()
try:
yield pm
finally:
if minimize_polling:
pm.stop()
class BasePollingManager(object):
def __init__(self):
self._force_polling = False
self._polling_completed = True
def force_polling(self):
self._force_polling = True
def polling_completed(self):
self._polling_completed = True
def _is_polling_required(self):
raise NotImplemented
@property
def is_polling_required(self):
# Always consume the updates to minimize polling.
polling_required = self._is_polling_required()
# Polling is required regardless of whether updates have been
# detected.
if self._force_polling:
self._force_polling = False
polling_required = True
# Polling is required if not yet done for previously detected
# updates.
if not self._polling_completed:
polling_required = True
if polling_required:
# Track whether polling has been completed to ensure that
# polling can be required until the caller indicates via a
# call to polling_completed() that polling has been
# successfully performed.
self._polling_completed = False
return polling_required
class AlwaysPoll(BasePollingManager):
@property
def is_polling_required(self):
return True
class InterfacePollingMinimizer(BasePollingManager):
"""Monitors ovsdb to determine when polling is required."""
def __init__(self, root_helper=None):
super(InterfacePollingMinimizer, self).__init__()
self._monitor = ovsdb_monitor.SimpleInterfaceMonitor(
root_helper=root_helper)
def start(self):
self._monitor.start()
def stop(self):
self._monitor.stop()
def _is_polling_required(self):
# Maximize the chances of update detection having a chance to
# collect output.
eventlet.sleep()
return self._monitor.has_updates