Insert a retry delay for DB reconnects in db.py, and make sure we
close the existing connection before trying to re-connect.
Signed-off-by: John Admanski <jadmanski@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@1461 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/db.py b/tko/db.py
index 5f4925d..656f267 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -1,4 +1,4 @@
-import re, os, sys, types, time
+import re, os, sys, types, time, random
import common
from autotest_lib.client.common_lib import global_config
@@ -9,31 +9,14 @@
class db_sql:
- def __init__(self, debug = False, autocommit=True, host = None,
- database = None, user = None, password = None):
+ def __init__(self, debug=False, autocommit=True, host=None,
+ database=None, user=None, password=None):
self.debug = debug
self.autocommit = autocommit
- self.host = host
- self.database = database
- self.user = user
- self.password = password
+ self._load_config(host, database, user, password)
- # grab the global config
- c = global_config.global_config
-
- # grab the host, database
- if not self.host:
- self.host = c.get_config_value("TKO", "host")
- if not self.database:
- self.database = c.get_config_value("TKO", "database")
-
- # grab the user and password
- if not self.user:
- self.user = c.get_config_value("TKO", "user")
- if not self.password:
- self.password = c.get_config_value("TKO", "password")
-
+ self.con = None
self._init_db()
# if not present, insert statuses
@@ -53,21 +36,55 @@
self.machine_group = {}
+ def _load_config(self, host, database, user, password):
+ # grab the global config
+ get_value = global_config.global_config.get_config_value
+
+ # grab the host, database
+ if not host:
+ self.host = get_value("TKO", "host")
+ if not database:
+ self.database = get_value("TKO", "database")
+
+ # grab the user and password
+ if not user:
+ self.user = get_value("TKO", "user")
+ if not password:
+ self.password = get_value("TKO", "password")
+
+ # grab the timeout configuration
+ self.query_timeout = get_value("TKO", "query_timeout",
+ type=int, default=3600)
+ self.min_delay = get_value("TKO", "min_retry_delay", type=int,
+ default=20)
+ self.max_delay = get_value("TKO", "max_retry_delay", type=int,
+ default=60)
+
+
def _init_db(self):
+ # make sure we clean up any existing connection
+ if self.con:
+ self.con.close()
+ self.con = None
+
# create the db connection and cursor
self.con = self.connect(self.host, self.database,
self.user, self.password)
self.cur = self.con.cursor()
+ def _random_delay(self):
+ delay = random.randint(self.min_delay, self.max_delay)
+ time.sleep(delay)
+
+
def _run_with_retry(self, function, *args, **dargs):
"""Call function(*args, **dargs) until either it passes
without an operational error, or a timeout is reached. This
is intended for internal use with database functions, not
for generic use."""
OperationalError = _get_error_class("OperationalError")
- # TODO: make this configurable
- TIMEOUT = 3600 # one hour
+
success = False
start_time = time.time()
while not success:
@@ -76,10 +93,11 @@
except OperationalError:
stop_time = time.time()
elapsed_time = stop_time - start_time
- if elapsed_time > TIMEOUT:
+ if elapsed_time > self.query_timeout:
raise
else:
try:
+ self._random_delay()
self._init_db()
except OperationalError:
pass