[RFC patch iwhd] Reconnect to Mongo

Pete Zaitcev zaitcev at redhat.com
Wed Sep 14 04:39:49 UTC 2011


I noticed a while ago that iwhd fails to reconnect, but the work to supply
a native systemd file added priority to this (because I had to discard the
shell stub that Jim wrote, which checked for Mongo being up).

If I read Jeff's code right, he expected that client.connect() reset
the .failed. But actually it does not. So, although we actually reconnect,
the isFailed() always evaluates to true and we never get any cursors.
Unfortunately, it seems that there is NO WAY to reset the .failed,
except through checkConnect() thing, and that 1) only works if auto-
reconnect is enabled, and 2) is not a public method. It is called by
query() itself though.

The patch below deals with all this by simply enabling the auto-reconnect,
which basically does exactly what we did explicitly before, only it
happens inside query() now.

The main reason I want to cycle this through RFC is a couple of odd
cases where there's no easy way return a NULL. I think the patch is
not making it worse, the problem always was there... unless I'm missing
a C++ trick.

diff --git a/meta.cpp b/meta.cpp
index 7b3a5d7..e88839a 100644
--- a/meta.cpp
+++ b/meta.cpp
@@ -118,7 +118,8 @@ public:
 
 static RepoMeta *it;
 
-RepoMeta::RepoMeta ()
+RepoMeta::RepoMeta () :
+    client(true)
 {
 	if (!verbose) {
 		cout.rdbuf(0);
@@ -155,27 +156,14 @@ auto_ptr<DBClientCursor>
 RepoMeta::GetCursor (Query &q)
 {
 	auto_ptr<DBClientCursor> curs;
-	bool looping = false;
-
-	for (;;) {
-		if (!client.isFailed()) {
-		        curs = client.query(MAIN_TBL,q);
-		        if (curs.get()) {
-		                break;
-		        }
-		}
-		if (looping) {
-		        break;
-		}
-		try {
-		        client.connect(addr);
-		}
-		catch (ConnectException &ce) {
-		        log_msg(IW_LOG_INFO, "reconnection to %s failed", addr);
-		}
-		looping = true;
-	}
 
+	try {
+		curs = client.query(MAIN_TBL,q);
+	}
+	catch (ConnectException &ce) {
+		log_msg(IW_LOG_INFO, "reconnection to %s failed", addr);
+		curs.reset();
+	}
 	return curs;
 }
 
@@ -434,7 +422,13 @@ RepoQuery::RepoQuery (const char *bucket, const char *key, const char *qstr,
 		expr = NULL;
 	}
 
-	curs = parent.GetCursor(q).release();
+	tmp = parent.GetCursor(q);
+	if (!tmp.get()) {
+		/* TBD: What to do if this happens? */
+		log_msg(IW_LOG_INFO, "no cursor");
+		return;
+	}
+	curs = tmp.release();
 	bucket = NULL;
 	key = NULL;
 }
@@ -582,7 +576,7 @@ RepoMeta::GetSize (const char *bucket, const char *key)
 
 	q = QUERY("_bucket"<<bucket<<"_key"<<key);
 	curs = GetCursor(q);
-
+	/* TBD: What to do if GetCursor() fails to reconnect? */
 	if (!curs->more()) {
 		return 0;
 	}
@@ -651,7 +645,7 @@ RepoMeta::GetAttrList (const char *bucket, const char *key)
 
 	q = QUERY("_bucket"<<bucket<<"_key"<<key);
 	curs = GetCursor(q);
-
+	/* TBD: What to do if GetCursor() fails to reconnect? */
 	if (!curs->more()) {
 		return NULL;
 	}

-- Pete


More information about the iwhd-devel mailing list