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:
Jakub Libosvar 2016-05-16 18:07:32 +00:00 committed by Kevin Benton
parent 0c8417ed00
commit f49a25c088
5 changed files with 53 additions and 1 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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):

View File

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

View File

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