commit 4a5a4c5c48a7316955d2e1bfde041351a823985a Author: Pete Zaitcev zaitcev@redhat.com Date: Wed Sep 21 06:45:20 2011 +0200
iwhd: handle a lost-then-restored mongo connection
If I read the code right, the intent was that client.connect() reset the .failed flag. But actually it does not. So, although we actually reconnect, isFailed() always evaluates to true and we get no cursor. Unfortunately, it seems that there is NO WAY to reset .failed, except through checkConnect(), and that 1) works only if auto-reconnect is enabled, and 2) is not a public method. It is called by query() itself though.
This patch deals with all this simply by enabling auto-reconnect, which basically does exactly what we did explicitly before, only it happens inside query() now. * meta.cpp: Handle SocketException, too
However, this is not the complete solution. Further testing suggests that if you bombard iwhd with requests when mongo is not responding, eventually, iwhd will crash.
meta.cpp | 46 ++++++++++++++++++++++------------------------ 1 files changed, 22 insertions(+), 24 deletions(-) --- diff --git a/meta.cpp b/meta.cpp index 7b3a5d7..fa2c591 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,18 @@ 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(); + } + catch (SocketException &ce) { + log_msg(IW_LOG_INFO, "reconnection to %s failed", addr); + curs.reset(); + } return curs; }
@@ -434,7 +426,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 +580,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 +649,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; }
iwhd-commit@lists.fedorahosted.org