]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Do not autoreschedule routers if l3 agent is back online
authorOleg Bondarev <obondarev@mirantis.com>
Thu, 3 Dec 2015 14:39:20 +0000 (17:39 +0300)
committerOleg Bondarev <obondarev@mirantis.com>
Thu, 3 Dec 2015 16:33:29 +0000 (19:33 +0300)
If there are a lot of routers scheduled to l3 agent,
rescheduling all of them one by one might take quite a long
period of time - during that time some agents might get back
online. In this case we should skip rescheduling.

Closes-Bug: #1522436
Change-Id: If6df1f2878ea3379e8d2dba431de3e358e40189d

neutron/db/l3_agentschedulers_db.py
neutron/tests/unit/db/test_agentschedulers_db.py

index a7f984410abbaee5b94e39529bdebd1cacad6711..f0d1b11b92b0a59fdcbec5482b7e759503eec16a 100644 (file)
@@ -107,7 +107,16 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
             filter(sa.or_(l3_attrs_db.RouterExtraAttributes.ha == sql.false(),
                           l3_attrs_db.RouterExtraAttributes.ha == sql.null())))
         try:
+            agents_back_online = set()
             for binding in down_bindings:
+                if binding.l3_agent_id in agents_back_online:
+                    continue
+                else:
+                    agent = self._get_agent(context, binding.l3_agent_id)
+                    if agent.is_active:
+                        agents_back_online.add(binding.l3_agent_id)
+                        continue
+
                 agent_mode = self._get_agent_mode(binding.l3_agent)
                 if agent_mode == constants.L3_AGENT_MODE_DVR:
                     # rescheduling from l3 dvr agent on compute node doesn't
index dde3b3a20da2da069c541136b0547f77e1f9e40d..582794f099b47734e1d0232e788d6df5b591732f 100644 (file)
@@ -720,6 +720,26 @@ class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase):
                 self._take_down_agent_and_run_reschedule(DHCP_HOSTC)
                 self.assertFalse(rr.called)
 
+    def test_router_is_not_rescheduled_if_agent_is_back_online(self):
+        plugin = manager.NeutronManager.get_service_plugins().get(
+            service_constants.L3_ROUTER_NAT)
+        l3_rpc_cb = l3_rpc.L3RpcCallback()
+        agent = helpers.register_l3_agent(host=L3_HOSTA)
+        with self.router(),\
+                self.router(),\
+                mock.patch.object(plugin, 'reschedule_router') as rs_mock,\
+                mock.patch.object(plugin, '_get_agent') as get_agent_mock:
+
+            # schedule the routers to the agent
+            l3_rpc_cb.sync_routers(self.adminContext, host=L3_HOSTA)
+            self._take_down_agent_and_run_reschedule(L3_HOSTA)
+            # since _get_agent is mocked it will return Mock object and
+            # agent.is_active will return true, so no rescheduling will be done
+            self.assertFalse(rs_mock.called)
+            # should be called only once as for second router alive agent id
+            # will be in cache
+            get_agent_mock.assert_called_once_with(mock.ANY, agent['id'])
+
     def test_router_reschedule_from_dead_agent(self):
         with self.router():
             l3_rpc_cb = l3_rpc.L3RpcCallback()