ovsdb: Don't let block() wait indefinitely
Poller.block() calls select() on defined file descriptors. This patch
adds timeout to select() so it doesn't get stuck in case no fd is ready.
Also timeout was added when reading transaction results from queue.
Conflicts:
neutron/tests/functional/agent/test_l2_ovs_agent.py
Closes-Bug: 1567668
Change-Id: I7dbddd01409430ce93d8c23f04f02c46fb2a68c4
(cherry picked from commit c13d722f39
)
This commit is contained in:
parent
0c8417ed00
commit
f49a25c088
|
@ -356,6 +356,10 @@ class API(object):
|
|||
"""
|
||||
|
||||
|
||||
class TimeoutException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def val_to_py(val):
|
||||
"""Convert a json ovsdb return value to native python object"""
|
||||
if isinstance(val, collections.Sequence) and len(val) == 2:
|
||||
|
|
|
@ -54,7 +54,13 @@ class Transaction(api.Transaction):
|
|||
|
||||
def commit(self):
|
||||
self.ovsdb_connection.queue_txn(self)
|
||||
result = self.results.get()
|
||||
try:
|
||||
result = self.results.get(self.timeout)
|
||||
except Queue.Empty:
|
||||
raise api.TimeoutException(
|
||||
_("Commands %(commands)s exceeded timeout %(timeout)d "
|
||||
"seconds") % {'commands': self.commands,
|
||||
'timeout': self.timeout})
|
||||
if self.check_error:
|
||||
if isinstance(result, idlutils.ExceptionResult):
|
||||
if self.log_errors:
|
||||
|
|
|
@ -48,6 +48,8 @@ class BaseCommand(api.Command):
|
|||
", ".join("%s=%s" % (k, v) for k, v in command_info.items()
|
||||
if k not in ['api', 'result']))
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
|
||||
class AddBridgeCommand(BaseCommand):
|
||||
def __init__(self, api, name, may_exist, datapath_type):
|
||||
|
|
|
@ -91,6 +91,9 @@ class Connection(object):
|
|||
while True:
|
||||
self.idl.wait(self.poller)
|
||||
self.poller.fd_wait(self.txns.alert_fileno, poller.POLLIN)
|
||||
#TODO(jlibosva): Remove next line once losing connection to ovsdb
|
||||
# is solved.
|
||||
self.poller.timer_wait(self.timeout)
|
||||
self.poller.block()
|
||||
self.idl.run()
|
||||
txn = self.txns.get_nowait()
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (c) 2016 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 mock
|
||||
from six.moves import queue
|
||||
import testtools
|
||||
import unittest2
|
||||
|
||||
try:
|
||||
from ovs.db import idl # noqa
|
||||
except ImportError:
|
||||
raise unittest2.SkipTest(
|
||||
"Skip test since ovs requirement for PY3 doesn't support yet.")
|
||||
|
||||
from neutron.agent.ovsdb import api
|
||||
from neutron.agent.ovsdb import impl_idl
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
class TransactionTestCase(base.BaseTestCase):
|
||||
def test_commit_raises_exception_on_timeout(self):
|
||||
with mock.patch.object(queue, 'Queue') as mock_queue:
|
||||
transaction = impl_idl.Transaction(mock.sentinel, mock.Mock(), 0)
|
||||
mock_queue.return_value.get.side_effect = queue.Empty
|
||||
with testtools.ExpectedException(api.TimeoutException):
|
||||
transaction.commit()
|
Loading…
Reference in New Issue