Browse Source

Merge "Dynamically increase l3 router process queue green pool size" into stable/queens

changes/25/730825/1
Zuul 1 month ago
committed by Gerrit Code Review
parent
commit
8acde7d833
2 changed files with 47 additions and 2 deletions
  1. +20
    -2
      neutron/agent/l3/agent.py
  2. +27
    -0
      neutron/tests/functional/agent/l3/test_legacy_router.py

+ 20
- 2
neutron/agent/l3/agent.py View File

@@ -21,6 +21,7 @@ from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants as lib_const
from neutron_lib import context as n_context
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_context import context as common_context
from oslo_log import log as logging
@@ -65,6 +66,9 @@ LOG = logging.getLogger(__name__)
SYNC_ROUTERS_MAX_CHUNK_SIZE = 256
SYNC_ROUTERS_MIN_CHUNK_SIZE = 32

ROUTER_PROCESS_GREENLET_MAX = 32
ROUTER_PROCESS_GREENLET_MIN = 8


def log_verbose_exc(message, router_payload):
LOG.exception(message)
@@ -239,6 +243,8 @@ class L3NATAgent(ha.AgentMixin,
self.driver,
self.metadata_driver)

# L3 agent router processing green pool
self._pool = eventlet.GreenPool(size=ROUTER_PROCESS_GREENLET_MIN)
self._queue = queue.ResourceProcessingQueue()
super(L3NATAgent, self).__init__(host=self.conf.host)

@@ -356,6 +362,15 @@ class L3NATAgent(ha.AgentMixin,

return legacy_router.LegacyRouter(*args, **kwargs)

@lockutils.synchronized('resize_greenpool')
def _resize_process_pool(self):
self._pool_size = max([ROUTER_PROCESS_GREENLET_MIN,
min([ROUTER_PROCESS_GREENLET_MAX,
len(self.router_info)])])
LOG.info("Resizing router processing queue green pool size to: %d",
self._pool_size)
self._pool.resize(self._pool_size)

def _router_added(self, router_id, router):
ri = self._create_router(router_id, router)
registry.notify(resources.ROUTER, events.BEFORE_CREATE,
@@ -378,6 +393,8 @@ class L3NATAgent(ha.AgentMixin,
LOG.exception('Error while deleting router %s',
router_id)

self._resize_process_pool()

def _safe_router_removed(self, router_id):
"""Try to delete a router and return True if successful."""

@@ -419,6 +436,8 @@ class L3NATAgent(ha.AgentMixin,

registry.notify(resources.ROUTER, events.AFTER_DELETE, self, router=ri)

self._resize_process_pool()

def init_extension_manager(self, connection):
l3_ext_manager.register_opts(self.conf)
self.agent_api = l3_ext_api.L3AgentExtensionAPI(self.router_info)
@@ -655,9 +674,8 @@ class L3NATAgent(ha.AgentMixin,

def _process_routers_loop(self):
LOG.debug("Starting _process_routers_loop")
pool = eventlet.GreenPool(size=8)
while True:
pool.spawn_n(self._process_router_update)
self._pool.spawn_n(self._process_router_update)

# NOTE(kevinbenton): this is set to 1 second because the actual interval
# is controlled by a FixedIntervalLoopingCall in neutron/service.py that


+ 27
- 0
neutron/tests/functional/agent/l3/test_legacy_router.py View File

@@ -21,6 +21,7 @@ from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants as lib_constants

from neutron.agent.l3 import agent as l3_agent
from neutron.agent.l3 import namespace_manager
from neutron.agent.l3 import namespaces
from neutron.agent.linux import ip_lib
@@ -107,6 +108,32 @@ class L3AgentTestCase(framework.L3AgentTestFramework):

self.assertIsNone(device.route.get_gateway())

def test_router_processing_pool_size(self):
router_info_1 = self.generate_router_info(False)
r1 = self.manage_router(self.agent, router_info_1)
self.assertEqual(l3_agent.ROUTER_PROCESS_GREENLET_MIN,
self.agent._pool.size)

router_info_2 = self.generate_router_info(False)
r2 = self.manage_router(self.agent, router_info_2)
self.assertEqual(l3_agent.ROUTER_PROCESS_GREENLET_MIN,
self.agent._pool.size)

router_info_list = [r1, r2]
for _i in range(l3_agent.ROUTER_PROCESS_GREENLET_MAX + 1):
ri = self.generate_router_info(False)
rtr = self.manage_router(self.agent, ri)
router_info_list.append(rtr)

self.assertEqual(l3_agent.ROUTER_PROCESS_GREENLET_MAX,
self.agent._pool.size)

for router in router_info_list:
self.agent._router_removed(router.router_id)

self.assertEqual(l3_agent.ROUTER_PROCESS_GREENLET_MIN,
self.agent._pool.size)

def _make_bridge(self):
bridge = framework.get_ovs_bridge(utils.get_rand_name())
bridge.create()


Loading…
Cancel
Save