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
This commit is contained in:
ricolin 2023-07-06 23:01:35 +08:00
parent d5bf20cbcc
commit bed303e9b4
2 changed files with 17 additions and 5 deletions

View File

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

View File

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