summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2014-07-30 09:30:21 -0400
committermatt dannenberg <matt.dannenberg@10gen.com>2014-08-05 04:54:29 -0400
commit87fbf90ba0096550a32f6f9967f5daa44398e8c6 (patch)
treef7b468a27f500d6574f8a36f6240927b6de4df63 /src/mongo/db/repl
parent6b534d4275b913eb8eaa31ffdacc7e25b5494afa (diff)
downloadmongo-87fbf90ba0096550a32f6f9967f5daa44398e8c6.tar.gz
SERVER-14616 replace BSONObj with HandshakeArgs and eliminate redundant handshake method
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/handshake_args.cpp114
-rw-r--r--src/mongo/db/repl/handshake_args.h95
-rw-r--r--src/mongo/db/repl/repl_coordinator.h19
-rw-r--r--src/mongo/db/repl/repl_coordinator_hybrid.cpp22
-rw-r--r--src/mongo/db/repl/repl_coordinator_hybrid.h7
-rw-r--r--src/mongo/db/repl/repl_coordinator_impl.cpp27
-rw-r--r--src/mongo/db/repl/repl_coordinator_impl.h7
-rw-r--r--src/mongo/db/repl/repl_coordinator_impl_test.cpp45
-rw-r--r--src/mongo/db/repl/repl_coordinator_legacy.cpp59
-rw-r--r--src/mongo/db/repl/repl_coordinator_legacy.h12
-rw-r--r--src/mongo/db/repl/repl_coordinator_mock.cpp11
-rw-r--r--src/mongo/db/repl/repl_coordinator_mock.h7
-rw-r--r--src/mongo/db/repl/replset_commands.cpp17
-rw-r--r--src/mongo/db/repl/sync_source_feedback.cpp9
15 files changed, 287 insertions, 165 deletions
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index b4f855e923b..ecc9522a3fd 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -82,6 +82,7 @@ env.Library('replmocks',
env.Library('replica_set_messages',
[
+ 'handshake_args.cpp',
'member_config.cpp',
'repl_set_heartbeat_args.cpp',
'repl_set_heartbeat_response.cpp',
diff --git a/src/mongo/db/repl/handshake_args.cpp b/src/mongo/db/repl/handshake_args.cpp
new file mode 100644
index 00000000000..9a81c4ddadf
--- /dev/null
+++ b/src/mongo/db/repl/handshake_args.cpp
@@ -0,0 +1,114 @@
+/**
+ * Copyright 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/repl/handshake_args.h"
+
+#include "mongo/base/status.h"
+#include "mongo/bson/util/bson_check.h"
+#include "mongo/bson/util/bson_extract.h"
+#include "mongo/db/jsobj.h"
+
+namespace mongo {
+namespace repl {
+
+namespace {
+
+ const std::string kRIDFieldName = "handshake";
+ // TODO(danneberg) remove after 2.8 since this field is only allowed for backwards compatibility
+ const std::string kOldMemberConfigFieldName = "config";
+ const std::string kMemberIdFieldName = "member";
+
+ const std::string kLegalHandshakeFieldNames[] = {
+ kRIDFieldName,
+ kOldMemberConfigFieldName,
+ kMemberIdFieldName
+ };
+
+} // namespace
+
+ HandshakeArgs::HandshakeArgs() :
+ _hasRid(false),
+ _hasMemberId(false),
+ _rid(OID()),
+ _memberId(-1) {}
+
+ Status HandshakeArgs::initialize(const BSONObj& argsObj) {
+ Status status = bsonCheckOnlyHasFields("HandshakeArgs",
+ argsObj,
+ kLegalHandshakeFieldNames);
+ if (!status.isOK())
+ return status;
+
+ BSONElement oid;
+ status = bsonExtractTypedField(argsObj, kRIDFieldName, jstOID, &oid);
+ if (!status.isOK())
+ return status;
+ _rid = oid.OID();
+ _hasRid = true;
+
+ status = bsonExtractIntegerField(argsObj, kMemberIdFieldName, &_memberId);
+ if (!status.isOK()) {
+ // field not necessary for master slave, do not return NoSuchKey Error
+ if (status != ErrorCodes::NoSuchKey) {
+ return status;
+ }
+ _memberId = -1;
+ }
+ else {
+ _hasMemberId = true;
+ }
+
+ return Status::OK();
+ }
+
+ bool HandshakeArgs::isInitialized() const {
+ return _hasRid;
+ }
+
+ void HandshakeArgs::setRid(const OID& newVal) {
+ _rid = newVal;
+ _hasRid = true;
+ }
+
+ void HandshakeArgs::setMemberId(long long newVal) {
+ _memberId = newVal;
+ _hasMemberId = true;
+ }
+
+ BSONObj HandshakeArgs::toBSON() const {
+ invariant(isInitialized());
+ BSONObjBuilder builder;
+ builder.append(kRIDFieldName, _rid);
+ builder.append(kMemberIdFieldName, _memberId);
+ return builder.obj();
+ }
+
+} // namespace repl
+} // namespace mongo
diff --git a/src/mongo/db/repl/handshake_args.h b/src/mongo/db/repl/handshake_args.h
new file mode 100644
index 00000000000..b0d442aaaf6
--- /dev/null
+++ b/src/mongo/db/repl/handshake_args.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/db/jsobj.h"
+
+namespace mongo {
+
+ class Status;
+
+namespace repl {
+
+ /**
+ * Arguments to the handshake command.
+ */
+ class HandshakeArgs {
+ public:
+ HandshakeArgs();
+
+ /**
+ * Initializes this HandshakeArgs from the contents of args.
+ */
+ Status initialize(const BSONObj& argsObj);
+
+ /**
+ * Returns true if all required fields have been initialized.
+ */
+ bool isInitialized() const;
+
+ /**
+ * Gets the _id of the sender in their ReplSetConfig.
+ */
+ long long getMemberId() const { return _memberId; }
+
+ /**
+ * Gets the unique identifier of the sender, which is used to track replication progress.
+ */
+ OID getRid() const { return _rid; }
+
+ /**
+ * The below methods check whether or not value in the method name has been set.
+ */
+ bool hasRid() { return _hasRid; };
+ bool hasMemberId() { return _hasMemberId; };
+
+ /**
+ * The below methods set the value in the method name to 'newVal'.
+ */
+ void setRid(const OID& newVal);
+ void setMemberId(long long newVal);
+
+ /**
+ * Returns a BSONified version of the object.
+ * Should only be called if the mandatory fields have been set.
+ * Optional fields are only included if they have been set.
+ */
+ BSONObj toBSON() const;
+
+ private:
+ bool _hasRid;
+ bool _hasMemberId;
+
+ // look at the body of the isInitialized() function to see which fields are mandatory
+ OID _rid;
+ long long _memberId;
+ };
+
+} // namespace repl
+} // namespace mongo
diff --git a/src/mongo/db/repl/repl_coordinator.h b/src/mongo/db/repl/repl_coordinator.h
index 9f56b7233df..a3b509cb737 100644
--- a/src/mongo/db/repl/repl_coordinator.h
+++ b/src/mongo/db/repl/repl_coordinator.h
@@ -34,6 +34,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/repl/handshake_args.h"
#include "mongo/db/repl/member_state.h"
#include "mongo/db/repl/replication_executor.h"
#include "mongo/db/repl/repl_settings.h"
@@ -411,29 +412,15 @@ namespace repl {
BSONObjBuilder* resultObj) = 0;
/**
- * Handles an incoming replSetUpdatePosition command that contains a handshake.
- * returns the same codes as processHandshake below, as well as any of the normal replset
- * command ErrorCodes.
- * TODO(spencer): Remove this method in favor of just using processHandshake
- */
- virtual Status processReplSetUpdatePositionHandshake(const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj) = 0;
-
- /**
* Handles an incoming Handshake command (or a handshake from replSetUpdatePosition).
* Associates the node's 'remoteID' with its 'handshake' object. This association is used
* to update local.slaves and to forward the node's replication progress upstream when this
* node is being chained through.
*
- * Returns ErrorCodes::ProtocolError if the handshake is missing required fields and
- * ErrorCodes::NodeNotFound if no replica set member is found with the given member ID.
- *
- * TODO(spencer): Remove remoteID arg and get it from the handshake instead.
+ * Returns ErrorCodes::NodeNotFound if no replica set member exists with the given member ID
*/
virtual Status processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake) = 0;
+ const HandshakeArgs& handshake) = 0;
/**
* Returns once the oplog's most recent entry changes or after one second, whichever
diff --git a/src/mongo/db/repl/repl_coordinator_hybrid.cpp b/src/mongo/db/repl/repl_coordinator_hybrid.cpp
index 031cda0bd08..d1eccfe8b63 100644
--- a/src/mongo/db/repl/repl_coordinator_hybrid.cpp
+++ b/src/mongo/db/repl/repl_coordinator_hybrid.cpp
@@ -287,27 +287,11 @@ namespace repl {
return legacyStatus;
}
- Status HybridReplicationCoordinator::processReplSetUpdatePositionHandshake(
- const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj) {
- Status legacyStatus = _legacy.processReplSetUpdatePositionHandshake(txn,
- handshake,
- resultObj);
- // TODO(spencer): Can't call into the impl until it can load a valid config
- //BSONObjBuilder implResult;
- //Status implStatus = _impl.processReplSetUpdatePositionHandshake(txn,
- // handshake,
- // &implResult);
- return legacyStatus;
- }
-
Status HybridReplicationCoordinator::processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake) {
- Status legacyResponse = _legacy.processHandshake(txn, remoteID, handshake);
+ const HandshakeArgs& handshake) {
+ Status legacyResponse = _legacy.processHandshake(txn, handshake);
// TODO(spencer): Can't call into the impl until it can load a valid config
- //_impl.processHandshake(txn, remoteID, handshake);
+ //_impl.processHandshake(txn, handshake);
return legacyResponse;
}
diff --git a/src/mongo/db/repl/repl_coordinator_hybrid.h b/src/mongo/db/repl/repl_coordinator_hybrid.h
index 8ccb7e6f01c..af3bd912ee9 100644
--- a/src/mongo/db/repl/repl_coordinator_hybrid.h
+++ b/src/mongo/db/repl/repl_coordinator_hybrid.h
@@ -145,13 +145,8 @@ namespace repl {
const BSONArray& updates,
BSONObjBuilder* resultObj);
- virtual Status processReplSetUpdatePositionHandshake(const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj);
-
virtual Status processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake);
+ const HandshakeArgs& handshake);
virtual void waitUpToOneSecondForOptimeChange(const OpTime& ot);
diff --git a/src/mongo/db/repl/repl_coordinator_impl.cpp b/src/mongo/db/repl/repl_coordinator_impl.cpp
index 238f6a68611..097da80c257 100644
--- a/src/mongo/db/repl/repl_coordinator_impl.cpp
+++ b/src/mongo/db/repl/repl_coordinator_impl.cpp
@@ -655,33 +655,14 @@ namespace repl {
return Status::OK();
}
- Status ReplicationCoordinatorImpl::processReplSetUpdatePositionHandshake(
- const OperationContext* txn,
- const BSONObj& cmdObj,
- BSONObjBuilder* resultObj) {
- OID rid = cmdObj["handshake"].OID();
- Status status = processHandshake(txn, rid, cmdObj);
- if (!status.isOK()) {
- return status;
- }
-
- return Status::OK();
- }
-
Status ReplicationCoordinatorImpl::processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake) {
- LOG(2) << "Received handshake " << handshake << " from node with RID " << remoteID;
+ const HandshakeArgs& handshake) {
+ LOG(2) << "Received handshake " << handshake.toBSON();
boost::lock_guard<boost::mutex> lock(_mutex);
- SlaveInfo& slaveInfo = _slaveInfoMap[remoteID];
+ SlaveInfo& slaveInfo = _slaveInfoMap[handshake.getRid()];
if (_getReplicationMode_inlock() == modeReplSet) {
- if (!handshake.hasField("member")) {
- return Status(ErrorCodes::ProtocolError,
- str::stream() << "Handshake object did not contain \"member\" field. "
- "Handshake: " << handshake);
- }
- int memberID = handshake["member"].Int();
+ int memberID = handshake.getMemberId();
const MemberConfig* member = _rsConfig.findMemberByID(memberID);
if (!member) {
return Status(ErrorCodes::NodeNotFound,
diff --git a/src/mongo/db/repl/repl_coordinator_impl.h b/src/mongo/db/repl/repl_coordinator_impl.h
index f7aeaad9fa0..54511243db8 100644
--- a/src/mongo/db/repl/repl_coordinator_impl.h
+++ b/src/mongo/db/repl/repl_coordinator_impl.h
@@ -157,13 +157,8 @@ namespace repl {
const BSONArray& updates,
BSONObjBuilder* resultObj);
- virtual Status processReplSetUpdatePositionHandshake(const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj);
-
virtual Status processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake);
+ const HandshakeArgs& handshake);
virtual void waitUpToOneSecondForOptimeChange(const OpTime& ot);
diff --git a/src/mongo/db/repl/repl_coordinator_impl_test.cpp b/src/mongo/db/repl/repl_coordinator_impl_test.cpp
index 7f65ac95307..654a57b4fd6 100644
--- a/src/mongo/db/repl/repl_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/repl_coordinator_impl_test.cpp
@@ -430,19 +430,22 @@ namespace {
OID rid1 = OID::gen();
OID rid2 = OID::gen();
OID rid3 = OID::gen();
- BSONObj handshake1 = BSON("handshake" << rid1 <<
- "member" << 0 <<
- "config" << BSON("_id" << 0 << "host" << "test1:1234"));
- BSONObj handshake2 = BSON("handshake" << rid2 <<
- "member" << 1 <<
- "config" << BSON("_id" << 1 << "host" << "test2:1234"));
- BSONObj handshake3 = BSON("handshake" << rid3 <<
- "member" << 2 <<
- "config" << BSON("_id" << 2 << "host" << "test3:1234"));
+ HandshakeArgs handshake1;
+ handshake1.initialize(BSON("handshake" << rid1 <<
+ "member" << 0 <<
+ "config" << BSON("_id" << 0 << "host" << "test1:1234")));
+ HandshakeArgs handshake2;
+ handshake2.initialize(BSON("handshake" << rid2 <<
+ "member" << 1 <<
+ "config" << BSON("_id" << 1 << "host" << "test2:1234")));
+ HandshakeArgs handshake3;
+ handshake3.initialize(BSON("handshake" << rid3 <<
+ "member" << 2 <<
+ "config" << BSON("_id" << 2 << "host" << "test3:1234")));
OperationContextNoop txn;
- ASSERT_OK(coordinator->processHandshake(&txn, rid1, handshake1));
- ASSERT_OK(coordinator->processHandshake(&txn, rid2, handshake2));
- ASSERT_OK(coordinator->processHandshake(&txn, rid3, handshake3));
+ ASSERT_OK(coordinator->processHandshake(&txn, handshake1));
+ ASSERT_OK(coordinator->processHandshake(&txn, handshake2));
+ ASSERT_OK(coordinator->processHandshake(&txn, handshake3));
OpTime optime1(1, 1);
OpTime optime2(1, 2);
OpTime optime3(2, 1);
@@ -507,14 +510,16 @@ namespace {
// Have other nodes handshake us and make sure we process it right.
OID slave1RID = OID::gen();
OID slave2RID = OID::gen();
- BSONObj slave1Handshake = BSON("handshake" << slave1RID <<
- "member" << 0 <<
- "config" << BSON("_id" << 0 << "host" << "test1:1234"));
- BSONObj slave2Handshake = BSON("handshake" << slave2RID <<
- "member" << 2 <<
- "config" << BSON("_id" << 2 << "host" << "test2:1234"));
- ASSERT_OK(coordinator->processHandshake(&txn, slave1RID, slave1Handshake));
- ASSERT_OK(coordinator->processHandshake(&txn, slave2RID, slave2Handshake));
+ HandshakeArgs slave1Handshake;
+ slave1Handshake.initialize(BSON("handshake" << slave1RID <<
+ "member" << 0 <<
+ "config" << BSON("_id" << 0 << "host" << "test1:1234")));
+ HandshakeArgs slave2Handshake;
+ slave2Handshake.initialize(BSON("handshake" << slave2RID <<
+ "member" << 2 <<
+ "config" << BSON("_id" << 2 << "host" << "test2:1234")));
+ ASSERT_OK(coordinator->processHandshake(&txn, slave1Handshake));
+ ASSERT_OK(coordinator->processHandshake(&txn, slave2Handshake));
coordinator->prepareReplSetUpdatePositionCommandHandshakes(&txn, &handshakes);
ASSERT_EQUALS(3U, handshakes.size());
diff --git a/src/mongo/db/repl/repl_coordinator_legacy.cpp b/src/mongo/db/repl/repl_coordinator_legacy.cpp
index 69b56ff528b..9c1225dd2b6 100644
--- a/src/mongo/db/repl/repl_coordinator_legacy.cpp
+++ b/src/mongo/db/repl/repl_coordinator_legacy.cpp
@@ -47,6 +47,7 @@
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/repl/replset_commands.h"
#include "mongo/db/repl/rs.h"
+#include "mongo/db/repl/rs_config.h"
#include "mongo/db/repl/rs_initiate.h"
#include "mongo/db/repl/write_concern.h"
#include "mongo/db/write_concern_options.h"
@@ -382,13 +383,17 @@ namespace {
// Only update if ts is newer than what we have already
return Status::OK();
}
- BSONObj config = mapFindWithDefault(_ridConfigMap, rid, BSONObj());
- LOG(2) << "received notification that node with RID " << rid << " and config " << config
- << " has reached optime: " << ts.toStringPretty();
if (rid != getMyRID(txn)) {
- // TODO(spencer): Remove this invariant for backwards compatibility
- invariant(!config.isEmpty());
+ BSONObj config;
+ if (getReplicationMode() == modeReplSet) {
+ Member* mem = _ridMemberMap[rid];
+ invariant(mem);
+ config = BSON("_id" << mem->id());
+ }
+ LOG(2) << "received notification that node with RID " << rid << " and config "
+ << config << " has reached optime: " << ts.toStringPretty();
+
// This is what updates the progress information used for satisfying write concern
// and wakes up threads waiting for replication.
if (!updateSlaveTracking(BSON("_id" << rid), config, ts)) {
@@ -442,7 +447,6 @@ namespace {
for (SlaveOpTimeMap::const_iterator itr = _slaveOpTimeMap.begin();
itr != _slaveOpTimeMap.end(); ++itr) {
const OID& rid = itr->first;
- const BSONObj& config = mapFindWithDefault(_ridConfigMap, rid, BSONObj());
BSONObjBuilder entry(arrayBuilder.subobjStart());
entry.append("_id", rid);
entry.append("optime", itr->second);
@@ -453,6 +457,9 @@ namespace {
entry.append("config", theReplSet->myConfig().asBson());
}
else {
+ Member* member = _ridMemberMap[rid];
+ invariant(member);
+ BSONObj config = member->config().asBson();
entry.append("config", config);
}
}
@@ -958,48 +965,16 @@ namespace {
return Status::OK();
}
- Status LegacyReplicationCoordinator::processReplSetUpdatePositionHandshake(
- const OperationContext* txn, const BSONObj& cmdObj, BSONObjBuilder* resultObj) {
-
- OID rid = cmdObj["handshake"].OID();
- Status status = processHandshake(txn, rid, cmdObj);
- if (!status.isOK()) {
- return status;
- }
-
- // if we're a replset and aren't primary, pass the handshake along
- if (theReplSet && !theReplSet->isPrimary()) {
- theReplSet->syncSourceFeedback.forwardSlaveHandshake();
- }
- return Status::OK();
- }
-
Status LegacyReplicationCoordinator::processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake) {
- LOG(2) << "Received handshake " << handshake << " from node with RID " << remoteID;
+ const HandshakeArgs& handshake) {
+ LOG(2) << "Received handshake " << handshake.toBSON();
boost::lock_guard<boost::mutex> lock(_mutex);
- BSONObj configObj;
- if (handshake.hasField("config")) {
- configObj = handshake["config"].Obj().getOwned();
- } else {
- configObj = BSON("host" << txn->getClient()->clientAddress(true) <<
- "upgradeNeeded" << true);
- }
- _ridConfigMap[remoteID] = configObj;
-
if (getReplicationMode() != modeReplSet) {
return Status::OK();
}
- if (!handshake.hasField("member")) {
- return Status(ErrorCodes::ProtocolError,
- str::stream() << "Handshake object did not contain \"member\" field. "
- "Handshake" << handshake);
- }
-
- int memberID = handshake["member"].Int();
+ int memberID = handshake.getMemberId();
Member* member = theReplSet->getMutableMember(memberID);
// it is possible that a node that was removed in a reconfig tried to handshake this node
// in that case, the Member will no longer be in theReplSet's _members List and member
@@ -1010,7 +985,7 @@ namespace {
" could not be found in replica set config during handshake");
}
- _ridMemberMap[remoteID] = member;
+ _ridMemberMap[handshake.getRid()] = member;
theReplSet->syncSourceFeedback.forwardSlaveHandshake();
return Status::OK();
}
diff --git a/src/mongo/db/repl/repl_coordinator_legacy.h b/src/mongo/db/repl/repl_coordinator_legacy.h
index 9721b8be0be..0ec889e25aa 100644
--- a/src/mongo/db/repl/repl_coordinator_legacy.h
+++ b/src/mongo/db/repl/repl_coordinator_legacy.h
@@ -143,13 +143,8 @@ namespace repl {
const BSONArray& updates,
BSONObjBuilder* resultObj);
- virtual Status processReplSetUpdatePositionHandshake(const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj);
-
virtual Status processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake);
+ const HandshakeArgs& handshake);
virtual void waitUpToOneSecondForOptimeChange(const OpTime& ot);
@@ -170,12 +165,9 @@ namespace repl {
const Milliseconds& stepdownTime,
const Milliseconds& postStepdownWaitTime);
- // Mutex that protects the _ridConfigMap and the _slaveOpTimeMap;
+ // Mutex that protects the _slaveOpTimeMap
boost::mutex _mutex;
- // Map from RID to member config object
- std::map<OID, BSONObj> _ridConfigMap;
-
// Map from RID to Member pointer for replica set nodes
typedef std::map<OID, Member*> OIDMemberMap;
OIDMemberMap _ridMemberMap;
diff --git a/src/mongo/db/repl/repl_coordinator_mock.cpp b/src/mongo/db/repl/repl_coordinator_mock.cpp
index 615944cb107..891a46609a6 100644
--- a/src/mongo/db/repl/repl_coordinator_mock.cpp
+++ b/src/mongo/db/repl/repl_coordinator_mock.cpp
@@ -215,17 +215,8 @@ namespace repl {
return Status::OK();
}
- Status ReplicationCoordinatorMock::processReplSetUpdatePositionHandshake(
- const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj) {
- // TODO
- return Status::OK();
- }
-
Status ReplicationCoordinatorMock::processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake) {
+ const HandshakeArgs& handshake) {
return Status::OK();
}
diff --git a/src/mongo/db/repl/repl_coordinator_mock.h b/src/mongo/db/repl/repl_coordinator_mock.h
index 1bc85e8fb2b..b83e630f8b3 100644
--- a/src/mongo/db/repl/repl_coordinator_mock.h
+++ b/src/mongo/db/repl/repl_coordinator_mock.h
@@ -144,13 +144,8 @@ namespace repl {
const BSONArray& updates,
BSONObjBuilder* resultObj);
- virtual Status processReplSetUpdatePositionHandshake(const OperationContext* txn,
- const BSONObj& handshake,
- BSONObjBuilder* resultObj);
-
virtual Status processHandshake(const OperationContext* txn,
- const OID& remoteID,
- const BSONObj& handshake);
+ const HandshakeArgs& handshake);
virtual void waitUpToOneSecondForOptimeChange(const OpTime& ot);
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index 7b421ed06a0..98523e5e7ac 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -368,12 +368,21 @@ namespace repl {
// we have received a handshake, not an update message
// handshakes are done here to ensure the receiving end supports the update command
+ HandshakeArgs handshake;
+ status = handshake.initialize(cmdObj["handshake"].embeddedObject());
+ if (!status.isOK())
+ return appendCommandStatus(result, status);
+
+ if (!handshake.hasMemberId()) {
+ return appendCommandStatus(
+ result,
+ Status(ErrorCodes::NoSuchKey,
+ "replSetUpdatePosition handshake was missing 'member' field"));
+ }
+
return appendCommandStatus(
result,
- getGlobalReplicationCoordinator()->processReplSetUpdatePositionHandshake(
- txn,
- cmdObj["handshake"].embeddedObject(),
- &result));
+ getGlobalReplicationCoordinator()->processHandshake(txn, handshake));
}
uassert(16888, "optimes field should be an array with an object for each secondary",
diff --git a/src/mongo/db/repl/sync_source_feedback.cpp b/src/mongo/db/repl/sync_source_feedback.cpp
index ceafe6b6a19..c85f7357f1b 100644
--- a/src/mongo/db/repl/sync_source_feedback.cpp
+++ b/src/mongo/db/repl/sync_source_feedback.cpp
@@ -94,11 +94,14 @@ namespace repl {
}
bool SyncSourceFeedback::replHandshake(OperationContext* txn) {
+ ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator();
+ if (replCoord->getCurrentMemberState().primary()) {
+ // primary has no one to handshake to
+ return true;
+ }
// construct a vector of handshake obj for us as well as all chained members
std::vector<BSONObj> handshakeObjs;
- getGlobalReplicationCoordinator()->prepareReplSetUpdatePositionCommandHandshakes(
- txn,
- &handshakeObjs);
+ replCoord->prepareReplSetUpdatePositionCommandHandshakes(txn, &handshakeObjs);
LOG(1) << "handshaking upstream updater";
for (std::vector<BSONObj>::iterator it = handshakeObjs.begin();
it != handshakeObjs.end();