From b4c210ac58a6da0936c906d076fe71529e6d98f4 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Wed, 23 Aug 2023 00:13:39 +0000 Subject: [PATCH] Fix a possible receive timeout This patch fixes a possible receive timeout caused by a slow response from the driver agent. For example if the database is very slow. Change-Id: I9079030a5fef9dc44da242adab3c568666777451 --- octavia_lib/api/drivers/driver_lib.py | 16 ++++++++++++---- .../tests/unit/api/drivers/test_driver_lib.py | 2 +- ...e-receive-timeout-error-f6d2454c48eb10cf.yaml | 5 +++++ 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/Fix-possible-receive-timeout-error-f6d2454c48eb10cf.yaml diff --git a/octavia_lib/api/drivers/driver_lib.py b/octavia_lib/api/drivers/driver_lib.py index 99b6612..bf43c2f 100644 --- a/octavia_lib/api/drivers/driver_lib.py +++ b/octavia_lib/api/drivers/driver_lib.py @@ -58,11 +58,19 @@ class DriverLibrary(): def _recv(self, sock): size_str = b'' - char = sock.recv(1) begin = time.time() - while char != b'\n': - size_str += char - char = sock.recv(1) + while True: + try: + char = sock.recv(1) + except socket.timeout: + # We could have an overloaded DB and the query may take too + # long, so as long as DRIVER_AGENT_TIMEOUT hasn't expired, + # let's keep trying while not blocking everything. + pass + else: + if char == b'\n': + break + size_str += char if time.time() - begin > DRIVER_AGENT_TIMEOUT: raise driver_exceptions.DriverAgentTimeout( fault_string=('The driver agent did not respond in {} ' diff --git a/octavia_lib/tests/unit/api/drivers/test_driver_lib.py b/octavia_lib/tests/unit/api/drivers/test_driver_lib.py index c248fa2..267a7f1 100644 --- a/octavia_lib/tests/unit/api/drivers/test_driver_lib.py +++ b/octavia_lib/tests/unit/api/drivers/test_driver_lib.py @@ -45,7 +45,7 @@ class TestDriverLib(base.TestCase): @mock.patch('builtins.memoryview') def test_recv(self, mock_memoryview): mock_socket = mock.MagicMock() - mock_socket.recv.side_effect = [b'1', b'\n', b'2', b'\n', b'3', b'\n'] + mock_socket.recv.side_effect = [b'1', b'\n', b'2', b'3', b'\n'] mock_socket.recv_into.return_value = 1 mv_mock = mock.MagicMock() mock_memoryview.return_value = mv_mock diff --git a/releasenotes/notes/Fix-possible-receive-timeout-error-f6d2454c48eb10cf.yaml b/releasenotes/notes/Fix-possible-receive-timeout-error-f6d2454c48eb10cf.yaml new file mode 100644 index 0000000..1b39ce1 --- /dev/null +++ b/releasenotes/notes/Fix-possible-receive-timeout-error-f6d2454c48eb10cf.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed a possible receive timeout if the driver agent didn't respond inside + five seconds. For example if you have a very slow database.