Do not autoreschedule routers if l3 agent is back online

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
This commit is contained in:
Oleg Bondarev 2015-12-03 17:39:20 +03:00
parent 770624b13b
commit 9ec466cd42
2 changed files with 29 additions and 0 deletions

View 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

View 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()