Decrease rpc timeout after agent receives SIGTERM

The patch sets different timeout to rpc api objects in OVS agent after
SIGTERM is received. Given timeout is configurable. This action prevents
long waiting for rpc call() methods to timeout and decreases amount of time
needed to successfully stopping OVS agent.

DocImpact
Closes-Bug: 1408334

Change-Id: I3026775e813a74bad9e0bca3be1f535212a2e417
(cherry picked from commit d3af7b0d2e)
This commit is contained in:
Jakub Libosvar 2015-01-30 18:30:22 +01:00
parent 7694ba7b72
commit 7cd3d0c1b7
4 changed files with 35 additions and 1 deletions

View File

@ -149,6 +149,11 @@
#
# enable_distributed_routing = False
# (IntOpt) Set new timeout in seconds for new rpc calls after agent receives
# SIGTERM. If value is set to 0, rpc timeout won't be changed"
#
# quitting_rpc_timeout = 10
[securitygroup]
# Firewall driver for realizing neutron security group function.
# firewall_driver = neutron.agent.firewall.NoopFirewallDriver

View File

@ -140,7 +140,8 @@ class OVSNeutronAgent(n_rpc.RpcCallback,
ovsdb_monitor_respawn_interval=(
constants.DEFAULT_OVSDBMON_RESPAWN),
arp_responder=False,
use_veth_interconnection=False):
use_veth_interconnection=False,
quitting_rpc_timeout=None):
'''Constructor.
:param integ_br: name of the integration bridge.
@ -163,6 +164,8 @@ class OVSNeutronAgent(n_rpc.RpcCallback,
supported.
:param use_veth_interconnection: use veths instead of patch ports to
interconnect the integration bridge to physical bridges.
:param quitting_rpc_timeout: timeout in seconds for rpc calls after
SIGTERM is received
'''
super(OVSNeutronAgent, self).__init__()
self.use_veth_interconnection = use_veth_interconnection
@ -253,6 +256,8 @@ class OVSNeutronAgent(n_rpc.RpcCallback,
# The initialization is complete; we can start receiving messages
self.connection.consume_in_threads()
self.quitting_rpc_timeout = quitting_rpc_timeout
def _report_state(self):
# How many devices are likely used by a VM
self.agent_state.get('configurations')['devices'] = (
@ -1479,6 +1484,12 @@ class OVSNeutronAgent(n_rpc.RpcCallback,
def _handle_sigterm(self, signum, frame):
LOG.debug("Agent caught SIGTERM, quitting daemon loop.")
self.run_daemon_loop = False
if self.quitting_rpc_timeout:
self.set_rpc_timeout(self.quitting_rpc_timeout)
def set_rpc_timeout(self, timeout):
for rpc_api in (self.plugin_rpc, self.state_rpc):
rpc_api._client.timeout = timeout
def create_agent_config_map(config):
@ -1506,6 +1517,7 @@ def create_agent_config_map(config):
l2_population=config.AGENT.l2_population,
arp_responder=config.AGENT.arp_responder,
use_veth_interconnection=config.OVS.use_veth_interconnection,
quitting_rpc_timeout=config.AGENT.quitting_rpc_timeout
)
# If enable_tunneling is TRUE, set tunnel_type to default to GRE

View File

@ -94,6 +94,10 @@ agent_opts = [
"outgoing IP packet carrying GRE/VXLAN tunnel.")),
cfg.BoolOpt('enable_distributed_routing', default=False,
help=_("Make the l2 agent run in DVR mode.")),
cfg.IntOpt('quitting_rpc_timeout', default=10,
help=_("Set new timeout in seconds for new rpc calls after "
"agent receives SIGTERM. If value is set to 0, rpc "
"timeout won't be changed"))
]

View File

@ -104,6 +104,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
cfg.CONF.set_default('firewall_driver',
'neutron.agent.firewall.NoopFirewallDriver',
group='SECURITYGROUP')
cfg.CONF.set_default('quitting_rpc_timeout', 10, 'AGENT')
kwargs = ovs_neutron_agent.create_agent_config_map(cfg.CONF)
class MockFixedIntervalLoopingCall(object):
@ -1403,6 +1404,18 @@ class TestOvsNeutronAgent(base.BaseTestCase):
setup_int_br.assert_has_calls([mock.call()])
setup_phys_br.assert_has_calls([mock.call({})])
def test_set_rpc_timeout(self):
self.agent._handle_sigterm(None, None)
for rpc_client in (self.agent.plugin_rpc._client,
self.agent.state_rpc._client):
self.assertEqual(10, rpc_client.timeout)
def test_set_rpc_timeout_no_value(self):
self.agent.quitting_rpc_timeout = None
with mock.patch.object(self.agent, 'set_rpc_timeout') as mock_set_rpc:
self.agent._handle_sigterm(None, None)
self.assertFalse(mock_set_rpc.called)
class AncillaryBridgesTest(base.BaseTestCase):