Risk: Medium
Visibility: Should eliminate missing results errors due to the final
reparse failing because of intermittent db issues.

Adds an autoretry to the transactions used for the final reparse.

Signed-off-by: John Admanski <jadmanski@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@1567 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/db.py b/tko/db.py
index c197ba5..ac4b866 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -78,11 +78,15 @@
 		time.sleep(delay)
 
 
-	def _run_with_retry(self, function, *args, **dargs):
+	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."""
+		without an operational error, or a timeout is reached.
+		This will re-connect to the database, so it is NOT safe
+		to use this inside of a database transaction.
+
+		It can be safely used with transactions, but the
+		transaction start & end must be completely contained
+		within the call to 'function'."""
 		OperationalError = _get_error_class("OperationalError")
 
 		success = False
@@ -188,7 +192,10 @@
 			return self.cur.fetchall()
 
 		# run the query, re-trying after operational errors
-		return self._run_with_retry(exec_sql)
+		if self.autocommit:
+			return self.run_with_retry(exec_sql)
+		else:
+			return exec_sql()
 
 
 	def select_sql(self, fields, table, sql, values):
@@ -204,7 +211,10 @@
 			return self.cur.fetchall()
 
 		# run the query, re-trying after operational errors
-		return self._run_with_retry(exec_sql)
+		if self.autocommit:
+			return self.run_with_retry(exec_sql)
+		else:
+			return exec_sql()
 
 
 	def _exec_sql_with_commit(self, sql, values, commit):
@@ -213,7 +223,7 @@
 			def exec_sql():
 				self.cur.execute(sql, values)
 				self.con.commit()
-			self._run_with_retry(exec_sql)
+			self.run_with_retry(exec_sql)
 		else:
 			# take one shot at running the query
 			self.cur.execute(sql, values)
diff --git a/tko/parse.py b/tko/parse.py
index 1b96bab..6d88d83 100755
--- a/tko/parse.py
+++ b/tko/parse.py
@@ -140,8 +140,9 @@
 			jobpath = os.path.join(path, machine)
 			jobname = "%s/%s" % (os.path.basename(path), machine)
 			try:
-				parse_one(db, jobname, jobpath, reparse,
-					  mail_on_failure)
+				db.run_with_retry(parse_one, db, jobname,
+						  path, reparse,
+						  mail_on_failure)
 			except Exception:
 				traceback.print_exc()
 				continue
@@ -150,7 +151,8 @@
 		job_elements = path.split("/")[-level:]
 		jobname = "/".join(job_elements)
 		try:
-			parse_one(db, jobname, path, reparse, mail_on_failure)
+			db.run_with_retry(parse_one, db, jobname, path,
+					  reparse, mail_on_failure)
 		except Exception:
 			traceback.print_exc()