diff options
author | Randolph Tan <randolph@10gen.com> | 2012-09-24 13:58:00 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2012-11-06 15:41:16 -0500 |
commit | 67d9b0daa4f444661cf846d07f6a97dfbd03e012 (patch) | |
tree | 87709741d2e90684441962bc2cbe159fee664ab3 | |
parent | c5bfd792bd6b53ebb753784d3786a7afeb4ccfbb (diff) | |
download | mongo-67d9b0daa4f444661cf846d07f6a97dfbd03e012.tar.gz |
SERVER-7111 DBClientReplicaSet::connect should not assert if primary is down but secondaries are available
-rw-r--r-- | jstests/sharding/read_pref_rs_client.js | 5 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.cpp | 27 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.h | 16 |
3 files changed, 26 insertions, 22 deletions
diff --git a/jstests/sharding/read_pref_rs_client.js b/jstests/sharding/read_pref_rs_client.js index df9a7ee1327..af7eac5d09a 100644 --- a/jstests/sharding/read_pref_rs_client.js +++ b/jstests/sharding/read_pref_rs_client.js @@ -180,12 +180,7 @@ function noPriSecOkTest() { coll.find().readPref('primary').explain(); }); - // Needs to restart server, otherwise the js Mongo constructor - // would throw because it can't find the primary - replTest.start(0, {}, true); - replTest.awaitSecondaryNodes(); replConn = new Mongo(replTest.getURL()); - replTest.stop(0); coll = replConn.getDB('test').user; var dest = coll.find().readPref('primaryPreferred').explain().server; assert.eq(SEC_HOST, dest); diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp index 8e00958403a..657731c40f0 100644 --- a/src/mongo/client/dbclient_rs.cpp +++ b/src/mongo/client/dbclient_rs.cpp @@ -1163,6 +1163,19 @@ namespace mongo { _check(true); } + bool ReplicaSetMonitor::isAnyNodeOk() const { + scoped_lock lock(_lock); + + for (vector<Node>::const_iterator iter = _nodes.begin(); + iter != _nodes.end(); ++iter) { + if (iter->ok) { + return true; + } + } + + return false; + } + bool ReplicaSetMonitor::Node::matchesTag(const BSONObj& tag) const { if (tag.isEmpty()) { return true; @@ -1347,19 +1360,7 @@ namespace mongo { } bool DBClientReplicaSet::connect() { - try { - checkMaster(); - } - catch (AssertionException&) { - // Can't use _getMonitor because that will create a new monitor from the cached seed if - // the monitor doesn't exist. - ReplicaSetMonitorPtr monitor = ReplicaSetMonitor::get(_setName); - if (_master && monitor ) { - monitor->notifyFailure(_masterHost); - } - return false; - } - return true; + return _getMonitor()->isAnyNodeOk(); } bool DBClientReplicaSet::auth(const string &dbname, const string &username, const string &pwd, string& errmsg, bool digestPassword, Auth::Level * level) { diff --git a/src/mongo/client/dbclient_rs.h b/src/mongo/client/dbclient_rs.h index 213ee0dad25..79d604384d8 100644 --- a/src/mongo/client/dbclient_rs.h +++ b/src/mongo/client/dbclient_rs.h @@ -262,6 +262,14 @@ namespace mongo { bool isHostCompatible(const HostAndPort& host, ReadPreference readPreference, const TagSet* tagSet) const; + /** + * Performs a quick check if at least one node is up based on the cached + * view of the set. + * + * @return true if any node is ok + */ + bool isAnyNodeOk() const; + private: /** * This populates a list of hosts from the list of seeds (discarding the @@ -405,10 +413,10 @@ namespace mongo { DBClientReplicaSet( const string& name , const vector<HostAndPort>& servers, double so_timeout=0 ); virtual ~DBClientReplicaSet(); - /** Returns false if nomember of the set were reachable, or neither is - * master, although, - * when false returned, you can still try to use this connection object, it will - * try reconnects. + /** + * Returns false if no member of the set were reachable. This object + * can still be used even when false was returned as it will try to + * reconnect when you use it later. */ bool connect(); |