Merge "sql: close connection for lock if not used"

This commit is contained in:
Jenkins 2017-04-27 20:16:25 +00:00 committed by Gerrit Code Review
commit ed15f7cc1c
2 changed files with 45 additions and 24 deletions

View File

@ -35,7 +35,7 @@ class MySQLLock(locking.Lock):
def __init__(self, name, parsed_url, options): def __init__(self, name, parsed_url, options):
super(MySQLLock, self).__init__(name) super(MySQLLock, self).__init__(name)
self.acquired = False self.acquired = False
self._conn = MySQLDriver.get_connection(parsed_url, options) self._conn = MySQLDriver.get_connection(parsed_url, options, True)
def acquire(self, blocking=True, shared=False): def acquire(self, blocking=True, shared=False):
@ -59,6 +59,8 @@ class MySQLLock(locking.Lock):
return False return False
try: try:
if not self._conn.open:
self._conn.connect()
with self._conn as cur: with self._conn as cur:
cur.execute("SELECT GET_LOCK(%s, 0);", self.name) cur.execute("SELECT GET_LOCK(%s, 0);", self.name)
# Can return NULL on error # Can return NULL on error
@ -66,6 +68,7 @@ class MySQLLock(locking.Lock):
self.acquired = True self.acquired = True
return True return True
except pymysql.MySQLError as e: except pymysql.MySQLError as e:
self._conn.close()
utils.raise_with_cause( utils.raise_with_cause(
tooz.ToozError, tooz.ToozError,
encodeutils.exception_to_unicode(e), encodeutils.exception_to_unicode(e),
@ -73,6 +76,7 @@ class MySQLLock(locking.Lock):
if blocking: if blocking:
raise _retry.TryAgain raise _retry.TryAgain
self._conn.close()
return False return False
return _lock() return _lock()
@ -84,8 +88,9 @@ class MySQLLock(locking.Lock):
with self._conn as cur: with self._conn as cur:
cur.execute("SELECT RELEASE_LOCK(%s);", self.name) cur.execute("SELECT RELEASE_LOCK(%s);", self.name)
cur.fetchone() cur.fetchone()
self.acquired = False self.acquired = False
return True self._conn.close()
return True
except pymysql.MySQLError as e: except pymysql.MySQLError as e:
utils.raise_with_cause(tooz.ToozError, utils.raise_with_cause(tooz.ToozError,
encodeutils.exception_to_unicode(e), encodeutils.exception_to_unicode(e),
@ -159,7 +164,7 @@ class MySQLDriver(coordination.CoordinationDriver):
raise tooz.NotImplemented raise tooz.NotImplemented
@staticmethod @staticmethod
def get_connection(parsed_url, options): def get_connection(parsed_url, options, defer_connect=False):
host = parsed_url.hostname host = parsed_url.hostname
port = parsed_url.port or MySQLLock.MYSQL_DEFAULT_PORT port = parsed_url.port or MySQLLock.MYSQL_DEFAULT_PORT
dbname = parsed_url.path[1:] dbname = parsed_url.path[1:]
@ -173,13 +178,15 @@ class MySQLDriver(coordination.CoordinationDriver):
port=port, port=port,
user=username, user=username,
passwd=password, passwd=password,
database=dbname) database=dbname,
defer_connect=defer_connect)
else: else:
return pymysql.Connect(host=host, return pymysql.Connect(host=host,
port=port, port=port,
user=username, user=username,
passwd=password, passwd=password,
database=dbname) database=dbname,
defer_connect=defer_connect)
except (pymysql.err.OperationalError, pymysql.err.InternalError) as e: except (pymysql.err.OperationalError, pymysql.err.InternalError) as e:
utils.raise_with_cause(coordination.ToozConnectionError, utils.raise_with_cause(coordination.ToozConnectionError,
encodeutils.exception_to_unicode(e), encodeutils.exception_to_unicode(e),

View File

@ -96,7 +96,9 @@ class PostgresLock(locking.Lock):
def __init__(self, name, parsed_url, options): def __init__(self, name, parsed_url, options):
super(PostgresLock, self).__init__(name) super(PostgresLock, self).__init__(name)
self.acquired = False self.acquired = False
self._conn = PostgresDriver.get_connection(parsed_url, options) self._conn = None
self._parsed_url = parsed_url
self._options = options
h = hashlib.md5() h = hashlib.md5()
h.update(name) h.update(name)
if six.PY2: if six.PY2:
@ -118,34 +120,46 @@ class PostgresLock(locking.Lock):
raise _retry.TryAgain raise _retry.TryAgain
return False return False
with _translating_cursor(self._conn) as cur: if not self._conn or self._conn.closed:
if blocking is True: self._conn = PostgresDriver.get_connection(self._parsed_url,
cur.execute("SELECT pg_advisory_lock(%s, %s);", self.key) self._options)
cur.fetchone() try:
self.acquired = True with _translating_cursor(self._conn) as cur:
return True if blocking is True:
else: cur.execute("SELECT pg_advisory_lock(%s, %s);",
cur.execute("SELECT pg_try_advisory_lock(%s, %s);", self.key)
self.key) cur.fetchone()
if cur.fetchone()[0] is True:
self.acquired = True self.acquired = True
return True return True
elif blocking is False:
return False
else: else:
raise _retry.TryAgain cur.execute("SELECT pg_try_advisory_lock(%s, %s);",
self.key)
if cur.fetchone()[0] is True:
self.acquired = True
return True
elif blocking is False:
self._conn.close()
return False
else:
raise _retry.TryAgain
except _retry.TryAgain:
pass # contine to retrieve lock on same conn
except Exception:
self._conn.close()
raise
return _lock() return _lock()
def release(self): def release(self):
if not self.acquired: if not self.acquired:
return False return False
with _translating_cursor(self._conn) as cur: with _translating_cursor(self._conn) as cur:
cur.execute("SELECT pg_advisory_unlock(%s, %s);", cur.execute("SELECT pg_advisory_unlock(%s, %s);", self.key)
self.key)
cur.fetchone() cur.fetchone()
self.acquired = False self.acquired = False
return True self._conn.close()
return True
def __del__(self): def __del__(self):
if self.acquired: if self.acquired: