From bed303e9b47b5aef3a9e2d6a5da4b5891e9e6689 Mon Sep 17 00:00:00 2001 From: ricolin Date: Thu, 6 Jul 2023 23:01:35 +0800 Subject: [PATCH] Fix: Add timeout for mysql driver The issue with current one is we try to use blocking as timeout provider. That make the timeout setting in mysql bound with blocking. And the lock can't served with scenario that when we don't need timeout blocking but still timeout required. Change-Id: I36c80f882a91cd1c63d5a3bc2d1d8cb50f6637c6 --- tooz/drivers/mysql.py | 6 ++---- tooz/tests/test_mysql.py | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tooz/drivers/mysql.py b/tooz/drivers/mysql.py index 8dc26911..54385603 100644 --- a/tooz/drivers/mysql.py +++ b/tooz/drivers/mysql.py @@ -37,7 +37,7 @@ class MySQLLock(locking.Lock): self.acquired = False self._conn = MySQLDriver.get_connection(parsed_url, options, True) - def acquire(self, blocking=True, shared=False): + def acquire(self, blocking=True, shared=False, timeout=0): if shared: raise tooz.NotImplemented @@ -58,14 +58,12 @@ class MySQLLock(locking.Lock): raise _retry.TryAgain return False - _, timeout = utils.convert_blocking(blocking) try: if not self._conn.open: self._conn.connect() cur = self._conn.cursor() cur.execute( - ("SELECT GET_LOCK(%s, " - f"{timeout if timeout is not None else '0'});"), + (f"SELECT GET_LOCK(%s, {timeout});"), self.name ) # Can return NULL on error diff --git a/tooz/tests/test_mysql.py b/tooz/tests/test_mysql.py index c2a39419..3b3c49cc 100644 --- a/tooz/tests/test_mysql.py +++ b/tooz/tests/test_mysql.py @@ -92,7 +92,21 @@ class TestMySQLDriver(testcase.TestCase): c.start() name = tests.get_random_uuid() - blocking_value = 10.12 + blocking_value = False + timeout = 10.1 + lock = c.get_lock(name) + with mock.patch.object(lock, 'acquire', wraps=True, autospec=True) as \ + mock_acquire: + with lock(blocking_value, timeout): + mock_acquire.assert_called_once_with(blocking_value, timeout) + + @mock.patch("pymysql.Connect") + def test_parsing_blocking_settings(self, sql_mock): + c = self._create_coordinator("mysql://localhost:3306/test") + c.start() + + name = tests.get_random_uuid() + blocking_value = True lock = c.get_lock(name) with mock.patch.object(lock, 'acquire', wraps=True, autospec=True) as \ mock_acquire: