summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMisha Tyulenev <misha@mongodb.com>2015-10-13 10:50:52 -0400
committerMisha Tyulenev <misha@mongodb.com>2015-10-13 11:25:41 -0400
commit920517cb2d6ca9eaf48b5be9b0f00360457667ca (patch)
tree57720a21f91eb2638a11b5c590853d058eaaaeba /src
parentcda9ac3ae9c629fbbd04819fecc8a74126ed6ea0 (diff)
downloadmongo-920517cb2d6ca9eaf48b5be9b0f00360457667ca.tar.gz
SERVER-20082 add maxTimeMs to config catalog operations
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp11
-rw-r--r--src/mongo/s/catalog/catalog_manager_common.cpp4
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog.h21
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog_impl.cpp57
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog_impl.h24
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp187
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog_mock.cpp22
-rw-r--r--src/mongo/s/catalog/dist_lock_catalog_mock.h21
-rw-r--r--src/mongo/s/catalog/dist_lock_manager.cpp19
-rw-r--r--src/mongo/s/catalog/dist_lock_manager.h13
-rw-r--r--src/mongo/s/catalog/dist_lock_manager_mock.cpp14
-rw-r--r--src/mongo/s/catalog/dist_lock_manager_mock.h7
-rw-r--r--src/mongo/s/catalog/forwarding_catalog_manager.cpp4
-rw-r--r--src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp10
-rw-r--r--src/mongo/s/catalog/legacy/config_upgrade.cpp2
-rw-r--r--src/mongo/s/catalog/legacy/legacy_dist_lock_manager.cpp15
-rw-r--r--src/mongo/s/catalog/legacy/legacy_dist_lock_manager.h8
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp27
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp3
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp5
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp14
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp5
-rw-r--r--src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp101
-rw-r--r--src/mongo/s/catalog/replset/replset_dist_lock_manager.h10
-rw-r--r--src/mongo/s/catalog/replset/replset_dist_lock_manager_test.cpp135
-rw-r--r--src/mongo/s/client/shard_registry.cpp59
-rw-r--r--src/mongo/s/client/shard_registry.h7
27 files changed, 497 insertions, 308 deletions
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index 54109d14bf7..da0714f12a3 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -166,6 +166,7 @@ Status parseRolePossessionManipulationCommands(const BSONObj& cmdObj,
validFieldNames.insert(cmdName.toString());
validFieldNames.insert("roles");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
if (!status.isOK()) {
@@ -212,6 +213,7 @@ Status parseCreateOrUpdateUserCommands(const BSONObj& cmdObj,
validFieldNames.insert("pwd");
validFieldNames.insert("roles");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
if (!status.isOK()) {
@@ -296,6 +298,7 @@ Status parseAndValidateDropUserCommand(const BSONObj& cmdObj,
unordered_set<std::string> validFieldNames;
validFieldNames.insert("dropUser");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "dropUser", validFieldNames);
if (!status.isOK()) {
@@ -324,6 +327,7 @@ Status parseFromDatabaseCommand(const BSONObj& cmdObj,
unordered_set<std::string> validFieldNames;
validFieldNames.insert(command);
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, command, validFieldNames);
if (!status.isOK()) {
@@ -348,6 +352,7 @@ Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfo
validFieldNames.insert("usersInfo");
validFieldNames.insert("showPrivileges");
validFieldNames.insert("showCredentials");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "usersInfo", validFieldNames);
if (!status.isOK()) {
@@ -394,6 +399,7 @@ Status parseRolesInfoCommand(const BSONObj& cmdObj, StringData dbname, RolesInfo
validFieldNames.insert("rolesInfo");
validFieldNames.insert("showPrivileges");
validFieldNames.insert("showBuiltinRoles");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames);
if (!status.isOK()) {
@@ -477,6 +483,7 @@ Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj,
validFieldNames.insert("privileges");
validFieldNames.insert("roles");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
if (!status.isOK()) {
@@ -537,6 +544,7 @@ Status parseAndValidateRolePrivilegeManipulationCommands(const BSONObj& cmdObj,
validFieldNames.insert(cmdName.toString());
validFieldNames.insert("privileges");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
if (!status.isOK()) {
@@ -584,6 +592,7 @@ Status parseDropRoleCommand(const BSONObj& cmdObj,
unordered_set<std::string> validFieldNames;
validFieldNames.insert("dropRole");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "dropRole", validFieldNames);
if (!status.isOK()) {
@@ -620,6 +629,7 @@ Status parseMergeAuthzCollectionsCommand(const BSONObj& cmdObj,
validFieldNames.insert("db");
validFieldNames.insert("drop");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "_mergeAuthzCollections", validFieldNames);
if (!status.isOK()) {
@@ -673,6 +683,7 @@ Status parseAuthSchemaUpgradeCommand(const BSONObj& cmdObj,
validFieldNames.insert("maxSteps");
validFieldNames.insert("upgradeShards");
validFieldNames.insert("writeConcern");
+ validFieldNames.insert("maxTimeMS");
Status status = _checkNoExtraFields(cmdObj, "authSchemaUpgrade", validFieldNames);
if (!status.isOK()) {
diff --git a/src/mongo/s/catalog/catalog_manager_common.cpp b/src/mongo/s/catalog/catalog_manager_common.cpp
index 92f9f6def61..14f2c3e5c8c 100644
--- a/src/mongo/s/catalog/catalog_manager_common.cpp
+++ b/src/mongo/s/catalog/catalog_manager_common.cpp
@@ -425,7 +425,7 @@ Status CatalogManagerCommon::createDatabase(OperationContext* txn, const std::st
// Lock the database globally to prevent conflicts with simultaneous database creation.
auto scopedDistLock =
- getDistLockManager()->lock(dbName, "createDatabase", Seconds{5}, Milliseconds{500});
+ getDistLockManager()->lock(txn, dbName, "createDatabase", Seconds{5}, Milliseconds{500});
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
@@ -509,7 +509,7 @@ Status CatalogManagerCommon::enableSharding(OperationContext* txn, const std::st
// Lock the database globally to prevent conflicts with simultaneous database
// creation/modification.
auto scopedDistLock =
- getDistLockManager()->lock(dbName, "enableSharding", Seconds{5}, Milliseconds{500});
+ getDistLockManager()->lock(txn, dbName, "enableSharding", Seconds{5}, Milliseconds{500});
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
diff --git a/src/mongo/s/catalog/dist_lock_catalog.h b/src/mongo/s/catalog/dist_lock_catalog.h
index 3c83e0433a7..516cff281d4 100644
--- a/src/mongo/s/catalog/dist_lock_catalog.h
+++ b/src/mongo/s/catalog/dist_lock_catalog.h
@@ -36,6 +36,7 @@ namespace mongo {
class LockpingsType;
class LocksType;
+class OperationContext;
class Status;
template <typename T>
class StatusWith;
@@ -66,13 +67,13 @@ public:
* Returns the ping document of the specified processID.
* Common status errors include socket errors.
*/
- virtual StatusWith<LockpingsType> getPing(StringData processID) = 0;
+ virtual StatusWith<LockpingsType> getPing(OperationContext* txn, StringData processID) = 0;
/**
* Updates the ping document. Creates a new entry if it does not exists.
* Common status errors include socket errors.
*/
- virtual Status ping(StringData processID, Date_t ping) = 0;
+ virtual Status ping(OperationContext* txn, StringData processID, Date_t ping) = 0;
/**
* Attempts to update the owner of a lock identified by lockID to lockSessionID.
@@ -90,7 +91,8 @@ public:
*
* Common status errors include socket and duplicate key errors.
*/
- virtual StatusWith<LocksType> grabLock(StringData lockID,
+ virtual StatusWith<LocksType> grabLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
StringData who,
StringData processId,
@@ -112,7 +114,8 @@ public:
*
* Common status errors include socket errors.
*/
- virtual StatusWith<LocksType> overtakeLock(StringData lockID,
+ virtual StatusWith<LocksType> overtakeLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
const OID& currentHolderTS,
StringData who,
@@ -124,31 +127,31 @@ public:
* Attempts to set the state of the lock document with lockSessionID to unlocked.
* Common status errors include socket errors.
*/
- virtual Status unlock(const OID& lockSessionID) = 0;
+ virtual Status unlock(OperationContext* txn, const OID& lockSessionID) = 0;
/**
* Get some information from the config server primary.
* Common status errors include socket errors.
*/
- virtual StatusWith<ServerInfo> getServerInfo() = 0;
+ virtual StatusWith<ServerInfo> getServerInfo(OperationContext* txn) = 0;
/**
* Returns the lock document.
* Returns LockNotFound if lock document doesn't exist.
* Common status errors include socket errors.
*/
- virtual StatusWith<LocksType> getLockByTS(const OID& lockSessionID) = 0;
+ virtual StatusWith<LocksType> getLockByTS(OperationContext* txn, const OID& lockSessionID) = 0;
/**
* Returns the lock document.
* Common status errors include socket errors.
*/
- virtual StatusWith<LocksType> getLockByName(StringData name) = 0;
+ virtual StatusWith<LocksType> getLockByName(OperationContext* txn, StringData name) = 0;
/**
* Attempts to delete the ping document corresponding to the given processId.
* Common status errors include socket errors.
*/
- virtual Status stopPing(StringData processId) = 0;
+ virtual Status stopPing(OperationContext* txn, StringData processId) = 0;
};
}
diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl.cpp b/src/mongo/s/catalog/dist_lock_catalog_impl.cpp
index 87c41729056..46108e3cf13 100644
--- a/src/mongo/s/catalog/dist_lock_catalog_impl.cpp
+++ b/src/mongo/s/catalog/dist_lock_catalog_impl.cpp
@@ -153,9 +153,10 @@ DistLockCatalogImpl::DistLockCatalogImpl(ShardRegistry* shardRegistry,
DistLockCatalogImpl::~DistLockCatalogImpl() = default;
-StatusWith<LockpingsType> DistLockCatalogImpl::getPing(StringData processID) {
+StatusWith<LockpingsType> DistLockCatalogImpl::getPing(OperationContext* txn,
+ StringData processID) {
auto findResult = _findOnConfig(
- kReadPref, _lockPingNS, BSON(LockpingsType::process() << processID), BSONObj(), 1);
+ txn, kReadPref, _lockPingNS, BSON(LockpingsType::process() << processID), BSONObj(), 1);
if (!findResult.isOK()) {
return findResult.getStatus();
@@ -179,7 +180,7 @@ StatusWith<LockpingsType> DistLockCatalogImpl::getPing(StringData processID) {
return pingDocResult.getValue();
}
-Status DistLockCatalogImpl::ping(StringData processID, Date_t ping) {
+Status DistLockCatalogImpl::ping(OperationContext* txn, StringData processID, Date_t ping) {
auto request =
FindAndModifyRequest::makeUpdate(_lockPingNS,
BSON(LockpingsType::process() << processID),
@@ -187,8 +188,8 @@ Status DistLockCatalogImpl::ping(StringData processID, Date_t ping) {
request.setUpsert(true);
request.setWriteConcern(_writeConcern);
- auto resultStatus =
- _client->runCommandOnConfigWithNotMasterRetries(_locksNS.db().toString(), request.toBSON());
+ auto resultStatus = _client->runCommandOnConfigWithNotMasterRetries(
+ txn, _locksNS.db().toString(), request.toBSON());
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -199,7 +200,8 @@ Status DistLockCatalogImpl::ping(StringData processID, Date_t ping) {
return findAndModifyStatus.getStatus();
}
-StatusWith<LocksType> DistLockCatalogImpl::grabLock(StringData lockID,
+StatusWith<LocksType> DistLockCatalogImpl::grabLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
StringData who,
StringData processId,
@@ -218,8 +220,8 @@ StatusWith<LocksType> DistLockCatalogImpl::grabLock(StringData lockID,
request.setShouldReturnNew(true);
request.setWriteConcern(_writeConcern);
- auto resultStatus =
- _client->runCommandOnConfigWithNotMasterRetries(_locksNS.db().toString(), request.toBSON());
+ auto resultStatus = _client->runCommandOnConfigWithNotMasterRetries(
+ txn, _locksNS.db().toString(), request.toBSON());
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -249,7 +251,8 @@ StatusWith<LocksType> DistLockCatalogImpl::grabLock(StringData lockID,
return locksTypeResult.getValue();
}
-StatusWith<LocksType> DistLockCatalogImpl::overtakeLock(StringData lockID,
+StatusWith<LocksType> DistLockCatalogImpl::overtakeLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
const OID& currentHolderTS,
StringData who,
@@ -271,8 +274,8 @@ StatusWith<LocksType> DistLockCatalogImpl::overtakeLock(StringData lockID,
request.setShouldReturnNew(true);
request.setWriteConcern(_writeConcern);
- auto resultStatus =
- _client->runCommandOnConfigWithNotMasterRetries(_locksNS.db().toString(), request.toBSON());
+ auto resultStatus = _client->runCommandOnConfigWithNotMasterRetries(
+ txn, _locksNS.db().toString(), request.toBSON());
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -296,15 +299,15 @@ StatusWith<LocksType> DistLockCatalogImpl::overtakeLock(StringData lockID,
return locksTypeResult.getValue();
}
-Status DistLockCatalogImpl::unlock(const OID& lockSessionID) {
+Status DistLockCatalogImpl::unlock(OperationContext* txn, const OID& lockSessionID) {
auto request = FindAndModifyRequest::makeUpdate(
_locksNS,
BSON(LocksType::lockID(lockSessionID)),
BSON("$set" << BSON(LocksType::state(LocksType::UNLOCKED))));
request.setWriteConcern(_writeConcern);
- auto resultStatus =
- _client->runCommandOnConfigWithNotMasterRetries(_locksNS.db().toString(), request.toBSON());
+ auto resultStatus = _client->runCommandOnConfigWithNotMasterRetries(
+ txn, _locksNS.db().toString(), request.toBSON());
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -324,8 +327,9 @@ Status DistLockCatalogImpl::unlock(const OID& lockSessionID) {
return findAndModifyStatus;
}
-StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogImpl::getServerInfo() {
- auto resultStatus = _client->runCommandOnConfig(kReadPref, "admin", BSON("serverStatus" << 1));
+StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogImpl::getServerInfo(OperationContext* txn) {
+ auto resultStatus =
+ _client->runCommandOnConfig(txn, kReadPref, "admin", BSON("serverStatus" << 1));
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -356,9 +360,10 @@ StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogImpl::getServerInfo() {
return DistLockCatalog::ServerInfo(localTimeElem.date(), electionIdStatus.getValue());
}
-StatusWith<LocksType> DistLockCatalogImpl::getLockByTS(const OID& lockSessionID) {
- auto findResult =
- _findOnConfig(kReadPref, _locksNS, BSON(LocksType::lockID(lockSessionID)), BSONObj(), 1);
+StatusWith<LocksType> DistLockCatalogImpl::getLockByTS(OperationContext* txn,
+ const OID& lockSessionID) {
+ auto findResult = _findOnConfig(
+ txn, kReadPref, _locksNS, BSON(LocksType::lockID(lockSessionID)), BSONObj(), 1);
if (!findResult.isOK()) {
return findResult.getStatus();
@@ -382,9 +387,9 @@ StatusWith<LocksType> DistLockCatalogImpl::getLockByTS(const OID& lockSessionID)
return locksTypeResult.getValue();
}
-StatusWith<LocksType> DistLockCatalogImpl::getLockByName(StringData name) {
+StatusWith<LocksType> DistLockCatalogImpl::getLockByName(OperationContext* txn, StringData name) {
auto findResult =
- _findOnConfig(kReadPref, _locksNS, BSON(LocksType::name() << name), BSONObj(), 1);
+ _findOnConfig(txn, kReadPref, _locksNS, BSON(LocksType::name() << name), BSONObj(), 1);
if (!findResult.isOK()) {
return findResult.getStatus();
@@ -408,13 +413,13 @@ StatusWith<LocksType> DistLockCatalogImpl::getLockByName(StringData name) {
return locksTypeResult.getValue();
}
-Status DistLockCatalogImpl::stopPing(StringData processId) {
+Status DistLockCatalogImpl::stopPing(OperationContext* txn, StringData processId) {
auto request =
FindAndModifyRequest::makeRemove(_lockPingNS, BSON(LockpingsType::process() << processId));
request.setWriteConcern(_writeConcern);
- auto resultStatus =
- _client->runCommandOnConfigWithNotMasterRetries(_locksNS.db().toString(), request.toBSON());
+ auto resultStatus = _client->runCommandOnConfigWithNotMasterRetries(
+ txn, _locksNS.db().toString(), request.toBSON());
if (!resultStatus.isOK()) {
return resultStatus.getStatus();
@@ -427,13 +432,15 @@ Status DistLockCatalogImpl::stopPing(StringData processId) {
}
StatusWith<vector<BSONObj>> DistLockCatalogImpl::_findOnConfig(
+ OperationContext* txn,
const ReadPreferenceSetting& readPref,
const NamespaceString& nss,
const BSONObj& query,
const BSONObj& sort,
boost::optional<long long> limit) {
repl::ReadConcernArgs readConcern(boost::none, repl::ReadConcernLevel::kMajorityReadConcern);
- auto result = _client->exhaustiveFindOnConfig(readPref, nss, query, sort, limit, readConcern);
+ auto result =
+ _client->exhaustiveFindOnConfig(txn, readPref, nss, query, sort, limit, readConcern);
if (!result.isOK()) {
return result.getStatus();
diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl.h b/src/mongo/s/catalog/dist_lock_catalog_impl.h
index a38aaf088f7..61047943dd6 100644
--- a/src/mongo/s/catalog/dist_lock_catalog_impl.h
+++ b/src/mongo/s/catalog/dist_lock_catalog_impl.h
@@ -51,18 +51,20 @@ public:
virtual ~DistLockCatalogImpl();
- virtual StatusWith<LockpingsType> getPing(StringData processID) override;
+ virtual StatusWith<LockpingsType> getPing(OperationContext* txn, StringData processID) override;
- virtual Status ping(StringData processID, Date_t ping) override;
+ virtual Status ping(OperationContext* txn, StringData processID, Date_t ping) override;
- virtual StatusWith<LocksType> grabLock(StringData lockID,
+ virtual StatusWith<LocksType> grabLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
StringData who,
StringData processId,
Date_t time,
StringData why) override;
- virtual StatusWith<LocksType> overtakeLock(StringData lockID,
+ virtual StatusWith<LocksType> overtakeLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
const OID& currentHolderTS,
StringData who,
@@ -70,18 +72,20 @@ public:
Date_t time,
StringData why) override;
- virtual Status unlock(const OID& lockSessionID) override;
+ virtual Status unlock(OperationContext* txn, const OID& lockSessionID) override;
- virtual StatusWith<ServerInfo> getServerInfo() override;
+ virtual StatusWith<ServerInfo> getServerInfo(OperationContext* txn) override;
- virtual StatusWith<LocksType> getLockByTS(const OID& lockSessionID) override;
+ virtual StatusWith<LocksType> getLockByTS(OperationContext* txn,
+ const OID& lockSessionID) override;
- virtual StatusWith<LocksType> getLockByName(StringData name) override;
+ virtual StatusWith<LocksType> getLockByName(OperationContext* txn, StringData name) override;
- virtual Status stopPing(StringData processId) override;
+ virtual Status stopPing(OperationContext* txn, StringData processId) override;
private:
- StatusWith<std::vector<BSONObj>> _findOnConfig(const ReadPreferenceSetting& readPref,
+ StatusWith<std::vector<BSONObj>> _findOnConfig(OperationContext* txn,
+ const ReadPreferenceSetting& readPref,
const NamespaceString& nss,
const BSONObj& query,
const BSONObj& sort,
diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp b/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp
index 88e6c7db50a..45d3f8cecdb 100644
--- a/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp
+++ b/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp
@@ -37,6 +37,7 @@
#include "mongo/client/remote_command_targeter_mock.h"
#include "mongo/db/commands.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/query/find_and_modify_request.h"
#include "mongo/db/repl/read_concern_args.h"
#include "mongo/executor/network_interface_mock.h"
@@ -103,6 +104,10 @@ public:
}
}
+ OperationContext* txn() {
+ return &_txn;
+ }
+
private:
void setUp() override {
auto networkUniquePtr = stdx::make_unique<executor::NetworkInterfaceMock>();
@@ -139,6 +144,7 @@ private:
std::unique_ptr<ShardRegistry> _shardRegistry;
std::unique_ptr<DistLockCatalogImpl> _distLockCatalog;
+ OperationContextNoop _txn;
};
void checkReadConcern(const BSONObj& findCmd) {
@@ -150,7 +156,7 @@ void checkReadConcern(const BSONObj& findCmd) {
TEST_F(DistLockCatalogFixture, BasicPing) {
auto future = launchAsync([this] {
Date_t ping(dateFromISOString("2014-03-11T09:17:18.098Z").getValue());
- auto status = catalog()->ping("abcd", ping);
+ auto status = catalog()->ping(txn(), "abcd", ping);
ASSERT_OK(status);
});
@@ -167,7 +173,8 @@ TEST_F(DistLockCatalogFixture, BasicPing) {
}
},
upsert: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -186,21 +193,21 @@ TEST_F(DistLockCatalogFixture, BasicPing) {
TEST_F(DistLockCatalogFixture, PingTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, PingRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, PingCommandError) {
auto future = launchAsync([this] {
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -218,7 +225,7 @@ TEST_F(DistLockCatalogFixture, PingCommandError) {
TEST_F(DistLockCatalogFixture, PingWriteError) {
auto future = launchAsync([this] {
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::Unauthorized, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -236,7 +243,7 @@ TEST_F(DistLockCatalogFixture, PingWriteError) {
TEST_F(DistLockCatalogFixture, PingWriteConcernError) {
auto future = launchAsync([this] {
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -257,7 +264,7 @@ TEST_F(DistLockCatalogFixture, PingWriteConcernError) {
TEST_F(DistLockCatalogFixture, PingUnsupportedWriteConcernResponse) {
auto future = launchAsync([this] {
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -279,7 +286,7 @@ TEST_F(DistLockCatalogFixture, PingUnsupportedWriteConcernResponse) {
TEST_F(DistLockCatalogFixture, PingUnsupportedResponseFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->ping("abcd", Date_t::now());
+ auto status = catalog()->ping(txn(), "abcd", Date_t::now());
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
});
@@ -296,7 +303,7 @@ TEST_F(DistLockCatalogFixture, GrabLockNoOp) {
OID myID("555f80be366c194b13fb0372");
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
auto resultStatus =
- catalog()->grabLock("test", myID, "me", "mongos", now, "because").getStatus();
+ catalog()->grabLock(txn(), "test", myID, "me", "mongos", now, "because").getStatus();
ASSERT_EQUALS(ErrorCodes::LockStateChangeFailed, resultStatus.code());
});
@@ -320,7 +327,8 @@ TEST_F(DistLockCatalogFixture, GrabLockNoOp) {
},
upsert: true,
new: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -335,7 +343,8 @@ TEST_F(DistLockCatalogFixture, GrabLockWithNewDoc) {
auto future = launchAsync([this] {
OID myID("555f80be366c194b13fb0372");
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
- auto resultStatus = catalog()->grabLock("test", myID, "me", "mongos", now, "because");
+ auto resultStatus =
+ catalog()->grabLock(txn(), "test", myID, "me", "mongos", now, "because");
ASSERT_OK(resultStatus.getStatus());
const auto& lockDoc = resultStatus.getValue();
@@ -366,7 +375,8 @@ TEST_F(DistLockCatalogFixture, GrabLockWithNewDoc) {
},
upsert: true,
new: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -396,7 +406,7 @@ TEST_F(DistLockCatalogFixture, GrabLockWithNewDoc) {
TEST_F(DistLockCatalogFixture, GrabLockWithBadLockDoc) {
auto future = launchAsync([this] {
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
- auto resultStatus = catalog()->grabLock("test", OID(), "", "", now, "").getStatus();
+ auto resultStatus = catalog()->grabLock(txn(), "test", OID(), "", "", now, "").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, resultStatus.code());
});
@@ -427,21 +437,22 @@ TEST_F(DistLockCatalogFixture, GrabLockWithBadLockDoc) {
TEST_F(DistLockCatalogFixture, GrabLockTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status = catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, GrabLockRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status = catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, GrabLockCommandError) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -459,7 +470,8 @@ TEST_F(DistLockCatalogFixture, GrabLockCommandError) {
TEST_F(DistLockCatalogFixture, GrabLockDupKeyError) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::LockStateChangeFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -477,7 +489,8 @@ TEST_F(DistLockCatalogFixture, GrabLockDupKeyError) {
TEST_F(DistLockCatalogFixture, GrabLockWriteError) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::Unauthorized, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -495,7 +508,8 @@ TEST_F(DistLockCatalogFixture, GrabLockWriteError) {
TEST_F(DistLockCatalogFixture, GrabLockWriteConcernError) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -516,7 +530,8 @@ TEST_F(DistLockCatalogFixture, GrabLockWriteConcernError) {
TEST_F(DistLockCatalogFixture, GrabLockWriteConcernErrorBadType) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::TypeMismatch, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -535,7 +550,8 @@ TEST_F(DistLockCatalogFixture, GrabLockWriteConcernErrorBadType) {
TEST_F(DistLockCatalogFixture, GrabLockResponseMissingValueField) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -551,7 +567,8 @@ TEST_F(DistLockCatalogFixture, GrabLockResponseMissingValueField) {
TEST_F(DistLockCatalogFixture, GrabLockUnsupportedWriteConcernResponse) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -573,7 +590,8 @@ TEST_F(DistLockCatalogFixture, GrabLockUnsupportedWriteConcernResponse) {
TEST_F(DistLockCatalogFixture, GrabLockUnsupportedResponseFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->grabLock("", OID::gen(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->grabLock(txn(), "", OID::gen(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
});
@@ -592,7 +610,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockNoOp) {
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
auto resultStatus =
catalog()
- ->overtakeLock("test", myID, currentOwner, "me", "mongos", now, "because")
+ ->overtakeLock(txn(), "test", myID, currentOwner, "me", "mongos", now, "because")
.getStatus();
ASSERT_EQUALS(ErrorCodes::LockStateChangeFailed, resultStatus.code());
@@ -621,7 +639,8 @@ TEST_F(DistLockCatalogFixture, OvertakeLockNoOp) {
}
},
new: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -637,8 +656,8 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWithNewDoc) {
OID myID("555f80be366c194b13fb0372");
OID currentOwner("555f99712c99a78c5b083358");
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
- auto resultStatus =
- catalog()->overtakeLock("test", myID, currentOwner, "me", "mongos", now, "because");
+ auto resultStatus = catalog()->overtakeLock(
+ txn(), "test", myID, currentOwner, "me", "mongos", now, "because");
ASSERT_OK(resultStatus.getStatus());
const auto& lockDoc = resultStatus.getValue();
@@ -673,7 +692,8 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWithNewDoc) {
}
},
new: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -704,7 +724,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWithBadLockDoc) {
auto future = launchAsync([this] {
Date_t now(dateFromISOString("2015-05-22T19:17:18.098Z").getValue());
auto resultStatus =
- catalog()->overtakeLock("test", OID(), OID(), "", "", now, "").getStatus();
+ catalog()->overtakeLock(txn(), "test", OID(), OID(), "", "", now, "").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, resultStatus.code());
});
@@ -735,14 +755,16 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWithBadLockDoc) {
TEST_F(DistLockCatalogFixture, OvertakeLockTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, OvertakeLockRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ auto status =
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
@@ -750,7 +772,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockRunCmdError) {
TEST_F(DistLockCatalogFixture, OvertakeLockCommandError) {
auto future = launchAsync([this] {
auto status =
- catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -769,7 +791,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockCommandError) {
TEST_F(DistLockCatalogFixture, OvertakeLockWriteError) {
auto future = launchAsync([this] {
auto status =
- catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::Unauthorized, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -788,7 +810,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWriteError) {
TEST_F(DistLockCatalogFixture, OvertakeLockWriteConcernError) {
auto future = launchAsync([this] {
auto status =
- catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -810,7 +832,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockWriteConcernError) {
TEST_F(DistLockCatalogFixture, OvertakeLockUnsupportedWriteConcernResponse) {
auto future = launchAsync([this] {
auto status =
- catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -833,7 +855,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockUnsupportedWriteConcernResponse) {
TEST_F(DistLockCatalogFixture, OvertakeLockUnsupportedResponseFormat) {
auto future = launchAsync([this] {
auto status =
- catalog()->overtakeLock("", OID(), OID(), "", "", Date_t::now(), "").getStatus();
+ catalog()->overtakeLock(txn(), "", OID(), OID(), "", "", Date_t::now(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
});
@@ -847,7 +869,7 @@ TEST_F(DistLockCatalogFixture, OvertakeLockUnsupportedResponseFormat) {
TEST_F(DistLockCatalogFixture, BasicUnlock) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID("555f99712c99a78c5b083358"));
+ auto status = catalog()->unlock(txn(), OID("555f99712c99a78c5b083358"));
ASSERT_OK(status);
});
@@ -859,7 +881,8 @@ TEST_F(DistLockCatalogFixture, BasicUnlock) {
findAndModify: "locks",
query: { ts: ObjectId("555f99712c99a78c5b083358") },
update: { $set: { state: 0 }},
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -879,7 +902,7 @@ TEST_F(DistLockCatalogFixture, BasicUnlock) {
TEST_F(DistLockCatalogFixture, UnlockWithNoNewDoc) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID("555f99712c99a78c5b083358"));
+ auto status = catalog()->unlock(txn(), OID("555f99712c99a78c5b083358"));
ASSERT_OK(status);
});
@@ -891,7 +914,8 @@ TEST_F(DistLockCatalogFixture, UnlockWithNoNewDoc) {
findAndModify: "locks",
query: { ts: ObjectId("555f99712c99a78c5b083358") },
update: { $set: { state: 0 }},
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -907,21 +931,21 @@ TEST_F(DistLockCatalogFixture, UnlockWithNoNewDoc) {
TEST_F(DistLockCatalogFixture, UnlockTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, UnlockRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, UnlockCommandError) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -939,7 +963,7 @@ TEST_F(DistLockCatalogFixture, UnlockCommandError) {
TEST_F(DistLockCatalogFixture, UnlockWriteError) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::Unauthorized, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -957,7 +981,7 @@ TEST_F(DistLockCatalogFixture, UnlockWriteError) {
TEST_F(DistLockCatalogFixture, UnlockWriteConcernError) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -978,7 +1002,7 @@ TEST_F(DistLockCatalogFixture, UnlockWriteConcernError) {
TEST_F(DistLockCatalogFixture, UnlockUnsupportedWriteConcernResponse) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1000,7 +1024,7 @@ TEST_F(DistLockCatalogFixture, UnlockUnsupportedWriteConcernResponse) {
TEST_F(DistLockCatalogFixture, UnlockUnsupportedResponseFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->unlock(OID());
+ auto status = catalog()->unlock(txn(), OID());
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
});
@@ -1016,7 +1040,7 @@ TEST_F(DistLockCatalogFixture, BasicGetServerInfo) {
auto future = launchAsync([this] {
Date_t localTime(dateFromISOString("2015-05-26T13:06:27.293Z").getValue());
OID electionID("555fa85d4d8640862a0fc79b");
- auto resultStatus = catalog()->getServerInfo();
+ auto resultStatus = catalog()->getServerInfo(txn());
ASSERT_OK(resultStatus.getStatus());
const auto& serverInfo = resultStatus.getValue();
@@ -1027,7 +1051,7 @@ TEST_F(DistLockCatalogFixture, BasicGetServerInfo) {
onCommand([](const RemoteCommandRequest& request) -> StatusWith<BSONObj> {
ASSERT_EQUALS(dummyHost, request.target);
ASSERT_EQUALS("admin", request.dbname);
- ASSERT_EQUALS(BSON("serverStatus" << 1), request.cmdObj);
+ ASSERT_EQUALS(BSON("serverStatus" << 1 << "maxTimeMS" << 30000), request.cmdObj);
return fromjson(R"({
localTime: { $date: "2015-05-26T13:06:27.293Z" },
@@ -1043,21 +1067,21 @@ TEST_F(DistLockCatalogFixture, BasicGetServerInfo) {
TEST_F(DistLockCatalogFixture, GetServerTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, GetServerRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, GetServerCommandError) {
auto future = launchAsync([this] {
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1075,7 +1099,7 @@ TEST_F(DistLockCatalogFixture, GetServerCommandError) {
TEST_F(DistLockCatalogFixture, GetServerBadElectionId) {
auto future = launchAsync([this] {
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1097,7 +1121,7 @@ TEST_F(DistLockCatalogFixture, GetServerBadElectionId) {
TEST_F(DistLockCatalogFixture, GetServerBadLocalTime) {
auto future = launchAsync([this] {
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1119,7 +1143,7 @@ TEST_F(DistLockCatalogFixture, GetServerBadLocalTime) {
TEST_F(DistLockCatalogFixture, GetServerNoGLEStats) {
auto future = launchAsync([this] {
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1136,7 +1160,7 @@ TEST_F(DistLockCatalogFixture, GetServerNoGLEStats) {
TEST_F(DistLockCatalogFixture, GetServerNoElectionId) {
auto future = launchAsync([this] {
- auto status = catalog()->getServerInfo().getStatus();
+ auto status = catalog()->getServerInfo(txn()).getStatus();
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1157,7 +1181,7 @@ TEST_F(DistLockCatalogFixture, GetServerNoElectionId) {
TEST_F(DistLockCatalogFixture, BasicStopPing) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("test");
+ auto status = catalog()->stopPing(txn(), "test");
ASSERT_OK(status);
});
@@ -1169,7 +1193,8 @@ TEST_F(DistLockCatalogFixture, BasicStopPing) {
findAndModify: "lockpings",
query: { _id: "test" },
remove: true,
- writeConcern: { w: "majority", wtimeout: 100 }
+ writeConcern: { w: "majority", wtimeout: 100 },
+ maxTimeMS: 30000
})"));
ASSERT_EQUALS(expectedCmd, request.cmdObj);
@@ -1188,21 +1213,21 @@ TEST_F(DistLockCatalogFixture, BasicStopPing) {
TEST_F(DistLockCatalogFixture, StopPingTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_NOT_OK(status);
}
TEST_F(DistLockCatalogFixture, StopPingRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, StopPingCommandError) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1220,7 +1245,7 @@ TEST_F(DistLockCatalogFixture, StopPingCommandError) {
TEST_F(DistLockCatalogFixture, StopPingWriteError) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::Unauthorized, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1238,7 +1263,7 @@ TEST_F(DistLockCatalogFixture, StopPingWriteError) {
TEST_F(DistLockCatalogFixture, StopPingWriteConcernError) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1259,7 +1284,7 @@ TEST_F(DistLockCatalogFixture, StopPingWriteConcernError) {
TEST_F(DistLockCatalogFixture, StopPingUnsupportedWriteConcernResponse) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1281,7 +1306,7 @@ TEST_F(DistLockCatalogFixture, StopPingUnsupportedWriteConcernResponse) {
TEST_F(DistLockCatalogFixture, StopPingUnsupportedResponseFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->stopPing("");
+ auto status = catalog()->stopPing(txn(), "");
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
});
@@ -1296,7 +1321,7 @@ TEST_F(DistLockCatalogFixture, StopPingUnsupportedResponseFormat) {
TEST_F(DistLockCatalogFixture, BasicGetPing) {
auto future = launchAsync([this] {
Date_t ping(dateFromISOString("2015-05-26T13:06:27.293Z").getValue());
- auto resultStatus = catalog()->getPing("test");
+ auto resultStatus = catalog()->getPing(txn(), "test");
ASSERT_OK(resultStatus.getStatus());
const auto& pingDoc = resultStatus.getValue();
@@ -1333,21 +1358,21 @@ TEST_F(DistLockCatalogFixture, BasicGetPing) {
TEST_F(DistLockCatalogFixture, GetPingTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->getPing("").getStatus();
+ auto status = catalog()->getPing(txn(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::InternalError, status.code());
}
TEST_F(DistLockCatalogFixture, GetPingRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->getPing("").getStatus();
+ auto status = catalog()->getPing(txn(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, GetPingNotFound) {
auto future = launchAsync([this] {
- auto status = catalog()->getPing("").getStatus();
+ auto status = catalog()->getPing(txn(), "").getStatus();
ASSERT_EQUALS(ErrorCodes::NoMatchingDocument, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1360,7 +1385,7 @@ TEST_F(DistLockCatalogFixture, GetPingNotFound) {
TEST_F(DistLockCatalogFixture, GetPingUnsupportedFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->getPing("test").getStatus();
+ auto status = catalog()->getPing(txn(), "test").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1384,7 +1409,7 @@ TEST_F(DistLockCatalogFixture, GetPingUnsupportedFormat) {
TEST_F(DistLockCatalogFixture, BasicGetLockByTS) {
auto future = launchAsync([this] {
OID ts("555f99712c99a78c5b083358");
- auto resultStatus = catalog()->getLockByTS(ts);
+ auto resultStatus = catalog()->getLockByTS(txn(), ts);
ASSERT_OK(resultStatus.getStatus());
const auto& lockDoc = resultStatus.getValue();
@@ -1418,20 +1443,20 @@ TEST_F(DistLockCatalogFixture, BasicGetLockByTS) {
TEST_F(DistLockCatalogFixture, GetLockByTSTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->getLockByTS(OID()).getStatus();
+ auto status = catalog()->getLockByTS(txn(), OID()).getStatus();
ASSERT_EQUALS(ErrorCodes::InternalError, status.code());
}
TEST_F(DistLockCatalogFixture, GetLockByTSRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->getLockByTS(OID()).getStatus();
+ auto status = catalog()->getLockByTS(txn(), OID()).getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, GetLockByTSNotFound) {
auto future = launchAsync([this] {
- auto status = catalog()->getLockByTS(OID()).getStatus();
+ auto status = catalog()->getLockByTS(txn(), OID()).getStatus();
ASSERT_EQUALS(ErrorCodes::LockNotFound, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1444,7 +1469,7 @@ TEST_F(DistLockCatalogFixture, GetLockByTSNotFound) {
TEST_F(DistLockCatalogFixture, GetLockByTSUnsupportedFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->getLockByTS(OID()).getStatus();
+ auto status = catalog()->getLockByTS(txn(), OID()).getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1468,7 +1493,7 @@ TEST_F(DistLockCatalogFixture, GetLockByTSUnsupportedFormat) {
TEST_F(DistLockCatalogFixture, BasicGetLockByName) {
auto future = launchAsync([this] {
OID ts("555f99712c99a78c5b083358");
- auto resultStatus = catalog()->getLockByName("abc");
+ auto resultStatus = catalog()->getLockByName(txn(), "abc");
ASSERT_OK(resultStatus.getStatus());
const auto& lockDoc = resultStatus.getValue();
@@ -1505,21 +1530,21 @@ TEST_F(DistLockCatalogFixture, BasicGetLockByName) {
TEST_F(DistLockCatalogFixture, GetLockByNameTargetError) {
targeter()->setFindHostReturnValue({ErrorCodes::InternalError, "can't target"});
- auto status = catalog()->getLockByName("x").getStatus();
+ auto status = catalog()->getLockByName(txn(), "x").getStatus();
ASSERT_EQUALS(ErrorCodes::InternalError, status.code());
}
TEST_F(DistLockCatalogFixture, GetLockByNameRunCmdError) {
shutdownShardRegistry();
- auto status = catalog()->getLockByName("x").getStatus();
+ auto status = catalog()->getLockByName(txn(), "x").getStatus();
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, status.code());
ASSERT_FALSE(status.reason().empty());
}
TEST_F(DistLockCatalogFixture, GetLockByNameNotFound) {
auto future = launchAsync([this] {
- auto status = catalog()->getLockByName("x").getStatus();
+ auto status = catalog()->getLockByName(txn(), "x").getStatus();
ASSERT_EQUALS(ErrorCodes::LockNotFound, status.code());
ASSERT_FALSE(status.reason().empty());
});
@@ -1532,7 +1557,7 @@ TEST_F(DistLockCatalogFixture, GetLockByNameNotFound) {
TEST_F(DistLockCatalogFixture, GetLockByNameUnsupportedFormat) {
auto future = launchAsync([this] {
- auto status = catalog()->getLockByName("x").getStatus();
+ auto status = catalog()->getLockByName(txn(), "x").getStatus();
ASSERT_EQUALS(ErrorCodes::FailedToParse, status.code());
ASSERT_FALSE(status.reason().empty());
});
diff --git a/src/mongo/s/catalog/dist_lock_catalog_mock.cpp b/src/mongo/s/catalog/dist_lock_catalog_mock.cpp
index f689a71fc36..03b5b0e85f6 100644
--- a/src/mongo/s/catalog/dist_lock_catalog_mock.cpp
+++ b/src/mongo/s/catalog/dist_lock_catalog_mock.cpp
@@ -125,7 +125,8 @@ DistLockCatalogMock::DistLockCatalogMock()
DistLockCatalogMock::~DistLockCatalogMock() {}
-StatusWith<LockpingsType> DistLockCatalogMock::getPing(StringData processID) {
+StatusWith<LockpingsType> DistLockCatalogMock::getPing(OperationContext* txn,
+ StringData processID) {
auto ret = kLockpingsTypeBadRetValue;
GetPingFunc checkerFunc = noGetPingSet;
@@ -139,7 +140,7 @@ StatusWith<LockpingsType> DistLockCatalogMock::getPing(StringData processID) {
return ret;
}
-Status DistLockCatalogMock::ping(StringData processID, Date_t ping) {
+Status DistLockCatalogMock::ping(OperationContext* txn, StringData processID, Date_t ping) {
auto ret = kBadRetValue;
PingFunc checkerFunc = noPingFuncSet;
@@ -153,7 +154,8 @@ Status DistLockCatalogMock::ping(StringData processID, Date_t ping) {
return ret;
}
-StatusWith<LocksType> DistLockCatalogMock::grabLock(StringData lockID,
+StatusWith<LocksType> DistLockCatalogMock::grabLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
StringData who,
StringData processId,
@@ -172,7 +174,8 @@ StatusWith<LocksType> DistLockCatalogMock::grabLock(StringData lockID,
return ret;
}
-StatusWith<LocksType> DistLockCatalogMock::overtakeLock(StringData lockID,
+StatusWith<LocksType> DistLockCatalogMock::overtakeLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
const OID& currentHolderTS,
StringData who,
@@ -192,7 +195,7 @@ StatusWith<LocksType> DistLockCatalogMock::overtakeLock(StringData lockID,
return ret;
}
-Status DistLockCatalogMock::unlock(const OID& lockSessionID) {
+Status DistLockCatalogMock::unlock(OperationContext* txn, const OID& lockSessionID) {
auto ret = kBadRetValue;
UnlockFunc checkerFunc = noUnLockFuncSet;
@@ -206,7 +209,7 @@ Status DistLockCatalogMock::unlock(const OID& lockSessionID) {
return ret;
}
-StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogMock::getServerInfo() {
+StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogMock::getServerInfo(OperationContext* txn) {
auto ret = kServerInfoBadRetValue;
GetServerInfoFunc checkerFunc = noGetServerInfoSet;
@@ -220,7 +223,8 @@ StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogMock::getServerInfo() {
return ret;
}
-StatusWith<LocksType> DistLockCatalogMock::getLockByTS(const OID& lockSessionID) {
+StatusWith<LocksType> DistLockCatalogMock::getLockByTS(OperationContext* txn,
+ const OID& lockSessionID) {
auto ret = kLocksTypeBadRetValue;
GetLockByTSFunc checkerFunc = noGetLockByTSSet;
@@ -234,7 +238,7 @@ StatusWith<LocksType> DistLockCatalogMock::getLockByTS(const OID& lockSessionID)
return ret;
}
-StatusWith<LocksType> DistLockCatalogMock::getLockByName(StringData name) {
+StatusWith<LocksType> DistLockCatalogMock::getLockByName(OperationContext* txn, StringData name) {
auto ret = kLocksTypeBadRetValue;
GetLockByNameFunc checkerFunc = noGetLockByNameSet;
@@ -248,7 +252,7 @@ StatusWith<LocksType> DistLockCatalogMock::getLockByName(StringData name) {
return ret;
}
-Status DistLockCatalogMock::stopPing(StringData processId) {
+Status DistLockCatalogMock::stopPing(OperationContext* txn, StringData processId) {
auto ret = kBadRetValue;
StopPingFunc checkerFunc = noStopPingFuncSet;
diff --git a/src/mongo/s/catalog/dist_lock_catalog_mock.h b/src/mongo/s/catalog/dist_lock_catalog_mock.h
index 2a1aa449a31..4a3e4af38d3 100644
--- a/src/mongo/s/catalog/dist_lock_catalog_mock.h
+++ b/src/mongo/s/catalog/dist_lock_catalog_mock.h
@@ -89,18 +89,20 @@ public:
using GetLockByNameFunc = stdx::function<void(StringData name)>;
using GetServerInfoFunc = stdx::function<void()>;
- virtual StatusWith<LockpingsType> getPing(StringData processID) override;
+ virtual StatusWith<LockpingsType> getPing(OperationContext* txn, StringData processID) override;
- virtual Status ping(StringData processID, Date_t ping) override;
+ virtual Status ping(OperationContext* txn, StringData processID, Date_t ping) override;
- virtual StatusWith<LocksType> grabLock(StringData lockID,
+ virtual StatusWith<LocksType> grabLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
StringData who,
StringData processId,
Date_t time,
StringData why) override;
- virtual StatusWith<LocksType> overtakeLock(StringData lockID,
+ virtual StatusWith<LocksType> overtakeLock(OperationContext* txn,
+ StringData lockID,
const OID& lockSessionID,
const OID& currentHolderTS,
StringData who,
@@ -108,15 +110,16 @@ public:
Date_t time,
StringData why) override;
- virtual Status unlock(const OID& lockSessionID) override;
+ virtual Status unlock(OperationContext* txn, const OID& lockSessionID) override;
- virtual StatusWith<ServerInfo> getServerInfo() override;
+ virtual StatusWith<ServerInfo> getServerInfo(OperationContext* txn) override;
- virtual StatusWith<LocksType> getLockByTS(const OID& lockSessionID) override;
+ virtual StatusWith<LocksType> getLockByTS(OperationContext* txn,
+ const OID& lockSessionID) override;
- virtual StatusWith<LocksType> getLockByName(StringData name) override;
+ virtual StatusWith<LocksType> getLockByName(OperationContext* txn, StringData name) override;
- virtual Status stopPing(StringData processId) override;
+ virtual Status stopPing(OperationContext* txn, StringData processId) override;
/**
* Sets the checker method to use and the return value for grabLock to return every
diff --git a/src/mongo/s/catalog/dist_lock_manager.cpp b/src/mongo/s/catalog/dist_lock_manager.cpp
index 9662bbff3af..d45765bd9aa 100644
--- a/src/mongo/s/catalog/dist_lock_manager.cpp
+++ b/src/mongo/s/catalog/dist_lock_manager.cpp
@@ -39,26 +39,29 @@ namespace mongo {
const stdx::chrono::milliseconds DistLockManager::kDefaultSingleLockAttemptTimeout(0);
const stdx::chrono::milliseconds DistLockManager::kDefaultLockRetryInterval(1000);
-DistLockManager::ScopedDistLock::ScopedDistLock(DistLockHandle lockHandle,
+DistLockManager::ScopedDistLock::ScopedDistLock(OperationContext* txn,
+ DistLockHandle lockHandle,
DistLockManager* lockManager)
- : _lockID(std::move(lockHandle)), _lockManager(lockManager) {}
+ : _txn(txn), _lockID(std::move(lockHandle)), _lockManager(lockManager) {}
DistLockManager::ScopedDistLock::~ScopedDistLock() {
if (_lockManager) {
- _lockManager->unlock(_lockID);
+ _lockManager->unlock(_txn, _lockID);
}
}
-DistLockManager::ScopedDistLock::ScopedDistLock(ScopedDistLock&& other) : _lockManager(nullptr) {
+DistLockManager::ScopedDistLock::ScopedDistLock(ScopedDistLock&& other)
+ : _txn(nullptr), _lockManager(nullptr) {
*this = std::move(other);
}
DistLockManager::ScopedDistLock& DistLockManager::ScopedDistLock::operator=(
ScopedDistLock&& other) {
if (this != &other) {
- if (_lockManager) {
- _lockManager->unlock(_lockID);
- }
+ invariant(_lockManager == nullptr);
+ invariant(_txn == nullptr);
+
+ _txn = other._txn;
_lockID = std::move(other._lockID);
_lockManager = other._lockManager;
other._lockManager = nullptr;
@@ -72,6 +75,6 @@ Status DistLockManager::ScopedDistLock::checkStatus() {
return Status(ErrorCodes::IllegalOperation, "no lock manager, lock was not acquired");
}
- return _lockManager->checkStatus(_lockID);
+ return _lockManager->checkStatus(_txn, _lockID);
}
}
diff --git a/src/mongo/s/catalog/dist_lock_manager.h b/src/mongo/s/catalog/dist_lock_manager.h
index 973c33aa782..15bdbdc2787 100644
--- a/src/mongo/s/catalog/dist_lock_manager.h
+++ b/src/mongo/s/catalog/dist_lock_manager.h
@@ -35,6 +35,7 @@
namespace mongo {
using DistLockHandle = OID;
+class OperationContext;
class Status;
template <typename T>
class StatusWith;
@@ -70,7 +71,9 @@ public:
MONGO_DISALLOW_COPYING(ScopedDistLock);
public:
- ScopedDistLock(DistLockHandle lockHandle, DistLockManager* lockManager);
+ ScopedDistLock(OperationContext* txn,
+ DistLockHandle lockHandle,
+ DistLockManager* lockManager);
~ScopedDistLock();
ScopedDistLock(ScopedDistLock&& other);
@@ -82,6 +85,7 @@ public:
Status checkStatus();
private:
+ OperationContext* _txn;
DistLockHandle _lockID;
DistLockManager* _lockManager; // Not owned here.
};
@@ -99,7 +103,7 @@ public:
* involves sending network messages. Implementation do not need to guarantee thread safety
* so callers should employ proper synchronization when calling this method.
*/
- virtual void shutDown(bool allowNetworking) = 0;
+ virtual void shutDown(OperationContext* txn, bool allowNetworking) = 0;
/**
* Tries multiple times to lock, using the specified lock try interval, until
@@ -115,6 +119,7 @@ public:
* Returns ErrorCodes::LockBusy if the lock is being held.
*/
virtual StatusWith<ScopedDistLock> lock(
+ OperationContext* txn,
StringData name,
StringData whyMessage,
stdx::chrono::milliseconds waitFor = kDefaultSingleLockAttemptTimeout,
@@ -125,11 +130,11 @@ protected:
* Unlocks the given lockHandle. Will attempt to retry again later if the config
* server is not reachable.
*/
- virtual void unlock(const DistLockHandle& lockHandle) = 0;
+ virtual void unlock(OperationContext* txn, const DistLockHandle& lockHandle) = 0;
/**
* Checks if the lockHandle still exists in the config server.
*/
- virtual Status checkStatus(const DistLockHandle& lockHandle) = 0;
+ virtual Status checkStatus(OperationContext* txn, const DistLockHandle& lockHandle) = 0;
};
}
diff --git a/src/mongo/s/catalog/dist_lock_manager_mock.cpp b/src/mongo/s/catalog/dist_lock_manager_mock.cpp
index 28dcbd5fa67..5afcfface61 100644
--- a/src/mongo/s/catalog/dist_lock_manager_mock.cpp
+++ b/src/mongo/s/catalog/dist_lock_manager_mock.cpp
@@ -59,12 +59,16 @@ DistLockManagerMock::DistLockManagerMock()
void DistLockManagerMock::startUp() {}
-void DistLockManagerMock::shutDown(bool allowNetworking) {
+void DistLockManagerMock::shutDown(OperationContext* txn, bool allowNetworking) {
uassert(28659, "DistLockManagerMock shut down with outstanding locks present", _locks.empty());
}
StatusWith<DistLockManager::ScopedDistLock> DistLockManagerMock::lock(
- StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) {
+ OperationContext* txn,
+ StringData name,
+ StringData whyMessage,
+ milliseconds waitFor,
+ milliseconds lockTryInterval) {
_lockChecker(name, whyMessage, waitFor, lockTryInterval);
_lockChecker = NoLockFuncSet;
@@ -84,10 +88,10 @@ StatusWith<DistLockManager::ScopedDistLock> DistLockManagerMock::lock(
info.lockID = DistLockHandle::gen();
_locks.push_back(info);
- return DistLockManager::ScopedDistLock(info.lockID, this);
+ return DistLockManager::ScopedDistLock(nullptr, info.lockID, this);
}
-void DistLockManagerMock::unlock(const DistLockHandle& lockHandle) {
+void DistLockManagerMock::unlock(OperationContext* txn, const DistLockHandle& lockHandle) {
std::vector<LockInfo>::iterator it =
std::find_if(_locks.begin(),
_locks.end(),
@@ -98,7 +102,7 @@ void DistLockManagerMock::unlock(const DistLockHandle& lockHandle) {
_locks.erase(it);
}
-Status DistLockManagerMock::checkStatus(const DistLockHandle& lockHandle) {
+Status DistLockManagerMock::checkStatus(OperationContext* txn, const DistLockHandle& lockHandle) {
return Status::OK();
}
diff --git a/src/mongo/s/catalog/dist_lock_manager_mock.h b/src/mongo/s/catalog/dist_lock_manager_mock.h
index fa3f05357c2..c7572738586 100644
--- a/src/mongo/s/catalog/dist_lock_manager_mock.h
+++ b/src/mongo/s/catalog/dist_lock_manager_mock.h
@@ -43,9 +43,10 @@ public:
virtual ~DistLockManagerMock() = default;
virtual void startUp() override;
- virtual void shutDown(bool allowNetworking) override;
+ virtual void shutDown(OperationContext* txn, bool allowNetworking) override;
virtual StatusWith<DistLockManager::ScopedDistLock> lock(
+ OperationContext* txn,
StringData name,
StringData whyMessage,
stdx::chrono::milliseconds waitFor,
@@ -59,9 +60,9 @@ public:
void expectLock(LockFunc checkerFunc, Status lockStatus);
protected:
- virtual void unlock(const DistLockHandle& lockHandle) override;
+ virtual void unlock(OperationContext* txn, const DistLockHandle& lockHandle) override;
- virtual Status checkStatus(const DistLockHandle& lockHandle) override;
+ virtual Status checkStatus(OperationContext* txn, const DistLockHandle& lockHandle) override;
private:
struct LockInfo {
diff --git a/src/mongo/s/catalog/forwarding_catalog_manager.cpp b/src/mongo/s/catalog/forwarding_catalog_manager.cpp
index f14dd5cd75a..f5b861cf467 100644
--- a/src/mongo/s/catalog/forwarding_catalog_manager.cpp
+++ b/src/mongo/s/catalog/forwarding_catalog_manager.cpp
@@ -132,8 +132,8 @@ StatusWith<ForwardingCatalogManager::ScopedDistLock> ForwardingCatalogManager::d
try {
_operationLock.lock_shared();
auto guard = MakeGuard([this] { _operationLock.unlock_shared(); });
- auto dlmLock =
- _actual->getDistLockManager()->lock(name, whyMessage, waitFor, lockTryInterval);
+ auto dlmLock = _actual->getDistLockManager()->lock(
+ txn, name, whyMessage, waitFor, lockTryInterval);
if (dlmLock.isOK()) {
guard.Dismiss(); // Don't unlock _operationLock; hold it until the returned
// ScopedDistLock goes out of scope!
diff --git a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
index 9908f683c88..31f06ee13d9 100644
--- a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
+++ b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
@@ -262,7 +262,7 @@ void CatalogManagerLegacy::shutDown(OperationContext* txn, bool allowNetworking)
_consistencyCheckerThread.join();
invariant(_distLockManager);
- _distLockManager->shutDown(allowNetworking);
+ _distLockManager->shutDown(txn, allowNetworking);
}
Status CatalogManagerLegacy::shardCollection(OperationContext* txn,
@@ -273,7 +273,7 @@ Status CatalogManagerLegacy::shardCollection(OperationContext* txn,
const set<ShardId>& initShardIds) {
// Lock the collection globally so that no other mongos can try to shard or drop the collection
// at the same time.
- auto scopedDistLock = getDistLockManager()->lock(ns, "shardCollection");
+ auto scopedDistLock = getDistLockManager()->lock(txn, ns, "shardCollection");
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
@@ -564,7 +564,8 @@ Status CatalogManagerLegacy::dropCollection(OperationContext* txn, const Namespa
waitFor = stdx::chrono::seconds(data["waitForSecs"].numberInt());
}
const stdx::chrono::milliseconds lockTryInterval(500);
- auto scopedDistLock = getDistLockManager()->lock(ns.ns(), "drop", waitFor, lockTryInterval);
+ auto scopedDistLock =
+ getDistLockManager()->lock(txn, ns.ns(), "drop", waitFor, lockTryInterval);
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
@@ -972,7 +973,8 @@ bool CatalogManagerLegacy::runUserManagementWriteCommand(OperationContext* txn,
dispatcher.addCommand(configServer, dbname, cmdObj);
}
- auto scopedDistLock = getDistLockManager()->lock("authorizationData", commandName, Seconds{5});
+ auto scopedDistLock =
+ getDistLockManager()->lock(txn, "authorizationData", commandName, Seconds{5});
if (!scopedDistLock.isOK()) {
return Command::appendCommandStatus(*result, scopedDistLock.getStatus());
}
diff --git a/src/mongo/s/catalog/legacy/config_upgrade.cpp b/src/mongo/s/catalog/legacy/config_upgrade.cpp
index f49043b6262..bddbdecb84b 100644
--- a/src/mongo/s/catalog/legacy/config_upgrade.cpp
+++ b/src/mongo/s/catalog/legacy/config_upgrade.cpp
@@ -297,7 +297,7 @@ Status checkAndInitConfigVersion(OperationContext* txn,
string whyMessage(stream() << "initializing config database to new format v"
<< CURRENT_CONFIG_VERSION);
auto lockTimeout = stdx::chrono::minutes(20);
- auto scopedDistLock = distLockManager->lock("configUpgrade", whyMessage, lockTimeout);
+ auto scopedDistLock = distLockManager->lock(txn, "configUpgrade", whyMessage, lockTimeout);
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
diff --git a/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.cpp b/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.cpp
index b7824d66d47..0651cdd4ca5 100644
--- a/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.cpp
+++ b/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.cpp
@@ -58,7 +58,7 @@ void LegacyDistLockManager::startUp() {
_pinger = stdx::make_unique<LegacyDistLockPinger>();
}
-void LegacyDistLockManager::shutDown(bool allowNetworking) {
+void LegacyDistLockManager::shutDown(OperationContext* txn, bool allowNetworking) {
stdx::unique_lock<stdx::mutex> sl(_mutex);
_isStopped = true;
@@ -72,7 +72,11 @@ void LegacyDistLockManager::shutDown(bool allowNetworking) {
}
StatusWith<DistLockManager::ScopedDistLock> LegacyDistLockManager::lock(
- StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) {
+ OperationContext* txn,
+ StringData name,
+ StringData whyMessage,
+ milliseconds waitFor,
+ milliseconds lockTryInterval) {
auto distLock = stdx::make_unique<DistributedLock>(_configServer, name.toString());
{
@@ -135,7 +139,7 @@ StatusWith<DistLockManager::ScopedDistLock> LegacyDistLockManager::lock(
_lockMap.insert(std::make_pair(lock.getLockID(), std::move(distLock)));
}
- return ScopedDistLock(lock.getLockID(), this);
+ return ScopedDistLock(txn, lock.getLockID(), this);
}
if (waitFor == milliseconds::zero())
@@ -161,7 +165,8 @@ StatusWith<DistLockManager::ScopedDistLock> LegacyDistLockManager::lock(
return lastStatus;
}
-void LegacyDistLockManager::unlock(const DistLockHandle& lockHandle) BOOST_NOEXCEPT {
+void LegacyDistLockManager::unlock(OperationContext* txn,
+ const DistLockHandle& lockHandle) BOOST_NOEXCEPT {
unique_ptr<DistributedLock> distLock;
{
@@ -185,7 +190,7 @@ void LegacyDistLockManager::unlock(const DistLockHandle& lockHandle) BOOST_NOEXC
}
}
-Status LegacyDistLockManager::checkStatus(const DistLockHandle& lockHandle) {
+Status LegacyDistLockManager::checkStatus(OperationContext* txn, const DistLockHandle& lockHandle) {
// Note: this should not happen when locks are managed through ScopedDistLock.
if (_pinger->willUnlockOID(lockHandle)) {
return Status(ErrorCodes::LockFailed,
diff --git a/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.h b/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.h
index 8267dd44602..85bc42bc042 100644
--- a/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.h
+++ b/src/mongo/s/catalog/legacy/legacy_dist_lock_manager.h
@@ -50,9 +50,10 @@ public:
virtual ~LegacyDistLockManager() = default;
virtual void startUp() override;
- virtual void shutDown(bool allowNetworking) override;
+ virtual void shutDown(OperationContext* txn, bool allowNetworking) override;
virtual StatusWith<DistLockManager::ScopedDistLock> lock(
+ OperationContext* txn,
StringData name,
StringData whyMessage,
stdx::chrono::milliseconds waitFor,
@@ -62,9 +63,10 @@ public:
void enablePinger(bool enable);
protected:
- virtual void unlock(const DistLockHandle& lockHandle) BOOST_NOEXCEPT override;
+ virtual void unlock(OperationContext* txn,
+ const DistLockHandle& lockHandle) BOOST_NOEXCEPT override;
- virtual Status checkStatus(const DistLockHandle& lockHandle) override;
+ virtual Status checkStatus(OperationContext* txn, const DistLockHandle& lockHandle) override;
private:
const ConnectionString _configServer;
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
index b70a12c79c3..acb2162f823 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
@@ -128,7 +128,7 @@ void CatalogManagerReplicaSet::shutDown(OperationContext* txn, bool allowNetwork
}
invariant(_distLockManager);
- _distLockManager->shutDown(allowNetworking);
+ _distLockManager->shutDown(txn, allowNetworking);
}
Status CatalogManagerReplicaSet::shardCollection(OperationContext* txn,
@@ -139,7 +139,7 @@ Status CatalogManagerReplicaSet::shardCollection(OperationContext* txn,
const set<ShardId>& initShardIds) {
// Lock the collection globally so that no other mongos can try to shard or drop the collection
// at the same time.
- auto scopedDistLock = getDistLockManager()->lock(ns, "shardCollection");
+ auto scopedDistLock = getDistLockManager()->lock(txn, ns, "shardCollection");
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
@@ -483,7 +483,8 @@ Status CatalogManagerReplicaSet::dropCollection(OperationContext* txn, const Nam
waitFor = stdx::chrono::seconds(data["waitForSecs"].numberInt());
}
const stdx::chrono::milliseconds lockTryInterval(500);
- auto scopedDistLock = getDistLockManager()->lock(ns.ns(), "drop", waitFor, lockTryInterval);
+ auto scopedDistLock =
+ getDistLockManager()->lock(txn, ns.ns(), "drop", waitFor, lockTryInterval);
if (!scopedDistLock.isOK()) {
return scopedDistLock.getStatus();
}
@@ -596,7 +597,7 @@ void CatalogManagerReplicaSet::logAction(OperationContext* txn, const ActionLogT
BSONObj createCmd = BSON("create" << ActionLogType::ConfigNS << "capped" << true << "size"
<< kActionLogCollectionSize);
auto result =
- grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries("config", createCmd);
+ grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(txn, "config", createCmd);
if (!result.isOK()) {
LOG(1) << "couldn't create actionlog collection: " << causedBy(result.getStatus());
return;
@@ -626,7 +627,7 @@ Status CatalogManagerReplicaSet::logChange(OperationContext* txn,
BSONObj createCmd = BSON("create" << ChangeLogType::ConfigNS << "capped" << true << "size"
<< kChangeLogCollectionSize);
auto result =
- grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries("config", createCmd);
+ grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(txn, "config", createCmd);
if (!result.isOK()) {
LOG(1) << "couldn't create changelog collection: " << causedBy(result.getStatus());
return result.getStatus();
@@ -866,12 +867,14 @@ bool CatalogManagerReplicaSet::runUserManagementWriteCommand(OperationContext* t
const std::string& dbname,
const BSONObj& cmdObj,
BSONObjBuilder* result) {
- auto scopedDistLock = getDistLockManager()->lock("authorizationData", commandName, Seconds{5});
+ auto scopedDistLock =
+ getDistLockManager()->lock(txn, "authorizationData", commandName, Seconds{5});
if (!scopedDistLock.isOK()) {
return Command::appendCommandStatus(*result, scopedDistLock.getStatus());
}
- auto response = grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(dbname, cmdObj);
+ auto response =
+ grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(txn, dbname, cmdObj);
if (!response.isOK()) {
return Command::appendCommandStatus(*result, response.getStatus());
}
@@ -901,7 +904,8 @@ Status CatalogManagerReplicaSet::applyChunkOpsDeprecated(OperationContext* txn,
const BSONArray& updateOps,
const BSONArray& preCondition) {
BSONObj cmd = BSON("applyOps" << updateOps << "preCondition" << preCondition);
- auto response = grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries("config", cmd);
+ auto response =
+ grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(txn, "config", cmd);
if (!response.isOK()) {
return response.getStatus();
@@ -929,7 +933,8 @@ void CatalogManagerReplicaSet::writeConfigServerDirect(OperationContext* txn,
invariant(dbname == "config" || dbname == "admin");
const BSONObj cmdObj = batchRequest.toBSON();
- auto response = grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(dbname, cmdObj);
+ auto response =
+ grid.shardRegistry()->runCommandOnConfigWithNotMasterRetries(txn, dbname, cmdObj);
if (!response.isOK()) {
_toBatchError(response.getStatus(), batchResponse);
return;
@@ -1181,7 +1186,7 @@ StatusWith<OpTimePair<vector<BSONObj>>> CatalogManagerReplicaSet::_exhaustiveFin
repl::ReadConcernLevel::kMajorityReadConcern};
auto result = grid.shardRegistry()->exhaustiveFindOnConfig(
- readPref, nss, query, sort, limit, readConcern);
+ txn, readPref, nss, query, sort, limit, readConcern);
if (ErrorCodes::isNetworkError(result.getStatus().code())) {
lastStatus = result.getStatus();
@@ -1212,7 +1217,7 @@ bool CatalogManagerReplicaSet::_runReadCommand(OperationContext* txn,
BSONObjBuilder* result) {
Status lastStatus = Status::OK();
for (int retry = 0; retry < kMaxReadRetry; retry++) {
- auto resultStatus = grid.shardRegistry()->runCommandOnConfig(settings, dbname, cmdObj);
+ auto resultStatus = grid.shardRegistry()->runCommandOnConfig(txn, settings, dbname, cmdObj);
if (ErrorCodes::isNetworkError(resultStatus.getStatus().code())) {
lastStatus = resultStatus.getStatus();
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp
index 9bf0a35041c..18b971ef1f0 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp
@@ -109,7 +109,8 @@ public:
BSONObj expectedCmd(fromjson(R"({
delete: "chunks",
deletes: [{ q: { ns: "test.user" }, limit: 0 }],
- writeConcern: { w: "majority" }
+ writeConcern: { w: "majority" },
+ maxTimeMS: 30000
})"));
ASSERT_EQ(expectedCmd, request.cmdObj);
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp
index a169cac4b76..1559260744a 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp
@@ -65,8 +65,9 @@ public:
ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata);
- BSONObj expectedCreateCmd = BSON("create" << ActionLogType::ConfigNS << "capped" << true
- << "size" << 1024 * 1024 * 2);
+ BSONObj expectedCreateCmd =
+ BSON("create" << ActionLogType::ConfigNS << "capped" << true << "size"
+ << 1024 * 1024 * 2 << "maxTimeMS" << 30000);
ASSERT_EQUALS(expectedCreateCmd, request.cmdObj);
return response;
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
index 0d560d0bdd5..47dd2befb6b 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
@@ -624,7 +624,7 @@ TEST_F(CatalogManagerReplSetTest, RunUserManagementReadCommand) {
request.metadata);
ASSERT_EQUALS("test", request.dbname);
- ASSERT_EQUALS(BSON("usersInfo" << 1), request.cmdObj);
+ ASSERT_EQUALS(BSON("usersInfo" << 1 << "maxTimeMS" << 30000), request.cmdObj);
return BSON("ok" << 1 << "users" << BSONArrayBuilder().arr());
});
@@ -701,7 +701,8 @@ TEST_F(CatalogManagerReplSetTest, RunUserManagementWriteCommandSuccess) {
onCommand([](const RemoteCommandRequest& request) {
ASSERT_EQUALS("test", request.dbname);
ASSERT_EQUALS(BSON("dropUser"
- << "test"),
+ << "test"
+ << "maxTimeMS" << 30000),
request.cmdObj);
ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata);
@@ -803,7 +804,8 @@ TEST_F(CatalogManagerReplSetTest, RunUserManagementWriteCommandNotMasterRetrySuc
ASSERT_EQUALS(host2, request.target);
ASSERT_EQUALS("test", request.dbname);
ASSERT_EQUALS(BSON("dropUser"
- << "test"),
+ << "test"
+ << "maxTimeMS" << 30000),
request.cmdObj);
ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata);
@@ -2083,7 +2085,8 @@ TEST_F(CatalogManagerReplSetTest, EnableShardingNoDBExists) {
multi: false,
upsert: true
}],
- writeConcern: { w: "majority" }
+ writeConcern: { w: "majority" },
+ maxTimeMS: 30000
})"));
ASSERT_EQ(expectedCmd, request.cmdObj);
@@ -2180,7 +2183,8 @@ TEST_F(CatalogManagerReplSetTest, EnableShardingDBExists) {
multi: false,
upsert: true
}],
- writeConcern: { w: "majority" }
+ writeConcern: { w: "majority" },
+ maxTimeMS: 30000
})"));
ASSERT_EQ(expectedCmd, request.cmdObj);
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp
index 6d3231d06b1..0d6b5cd315d 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp
@@ -281,8 +281,9 @@ void CatalogManagerReplSetTestFixture::expectChangeLogCreate(const HostAndPort&
onCommand([&](const RemoteCommandRequest& request) {
ASSERT_EQUALS(configHost, request.target);
ASSERT_EQUALS("config", request.dbname);
- BSONObj expectedCreateCmd = BSON("create" << ChangeLogType::ConfigNS << "capped" << true
- << "size" << 1024 * 1024 * 10);
+ BSONObj expectedCreateCmd =
+ BSON("create" << ChangeLogType::ConfigNS << "capped" << true << "size"
+ << 1024 * 1024 * 10 << "maxTimeMS" << 30000);
ASSERT_EQUALS(expectedCreateCmd, request.cmdObj);
return response;
diff --git a/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp b/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp
index 920c7bcb0b1..0be248e3b56 100644
--- a/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp
+++ b/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp
@@ -35,6 +35,7 @@
#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/s/catalog/dist_lock_catalog.h"
#include "mongo/s/catalog/type_lockpings.h"
#include "mongo/s/catalog/type_locks.h"
@@ -78,7 +79,7 @@ void ReplSetDistLockManager::startUp() {
}
}
-void ReplSetDistLockManager::shutDown(bool allowNetworking) {
+void ReplSetDistLockManager::shutDown(OperationContext* txn, bool allowNetworking) {
invariant(allowNetworking);
{
stdx::lock_guard<stdx::mutex> lk(_mutex);
@@ -93,7 +94,7 @@ void ReplSetDistLockManager::shutDown(bool allowNetworking) {
_execThread.reset();
}
- auto status = _catalog->stopPing(_processID);
+ auto status = _catalog->stopPing(txn, _processID);
if (!status.isOK()) {
warning() << "error encountered while cleaning up distributed ping entry for " << _processID
<< causedBy(status);
@@ -110,40 +111,45 @@ void ReplSetDistLockManager::doTask() {
<< " (sleeping for " << _pingInterval << ")";
Timer elapsedSincelastPing(_serviceContext->getTickSource());
+ Client::initThread("replSetDistLockPinger");
+
while (!isShutDown()) {
- auto pingStatus = _catalog->ping(_processID, Date_t::now());
+ {
+ auto txn = cc().makeOperationContext();
+ auto pingStatus = _catalog->ping(txn.get(), _processID, Date_t::now());
- if (!pingStatus.isOK()) {
- warning() << "pinging failed for distributed lock pinger" << causedBy(pingStatus);
- }
+ if (!pingStatus.isOK()) {
+ warning() << "pinging failed for distributed lock pinger" << causedBy(pingStatus);
+ }
- const milliseconds elapsed(elapsedSincelastPing.millis());
- if (elapsed > 10 * _pingInterval) {
- warning() << "Lock pinger for proc: " << _processID << " was inactive for " << elapsed
- << " ms";
- }
- elapsedSincelastPing.reset();
+ const milliseconds elapsed(elapsedSincelastPing.millis());
+ if (elapsed > 10 * _pingInterval) {
+ warning() << "Lock pinger for proc: " << _processID << " was inactive for "
+ << elapsed << " ms";
+ }
+ elapsedSincelastPing.reset();
- std::deque<DistLockHandle> toUnlockBatch;
- {
- stdx::unique_lock<stdx::mutex> lk(_mutex);
- toUnlockBatch.swap(_unlockList);
- }
+ std::deque<DistLockHandle> toUnlockBatch;
+ {
+ stdx::unique_lock<stdx::mutex> lk(_mutex);
+ toUnlockBatch.swap(_unlockList);
+ }
- for (const auto& toUnlock : toUnlockBatch) {
- auto unlockStatus = _catalog->unlock(toUnlock);
+ for (const auto& toUnlock : toUnlockBatch) {
+ auto unlockStatus = _catalog->unlock(txn.get(), toUnlock);
- if (!unlockStatus.isOK()) {
- warning() << "Failed to unlock lock with " << LocksType::lockID() << ": "
- << toUnlock << causedBy(unlockStatus);
- queueUnlock(toUnlock);
- } else {
- LOG(0) << "distributed lock with " << LocksType::lockID() << ": " << toUnlock
- << "' unlocked.";
- }
+ if (!unlockStatus.isOK()) {
+ warning() << "Failed to unlock lock with " << LocksType::lockID() << ": "
+ << toUnlock << causedBy(unlockStatus);
+ queueUnlock(toUnlock);
+ } else {
+ LOG(0) << "distributed lock with " << LocksType::lockID() << ": " << toUnlock
+ << "' unlocked.";
+ }
- if (isShutDown()) {
- return;
+ if (isShutDown()) {
+ return;
+ }
}
}
@@ -152,10 +158,11 @@ void ReplSetDistLockManager::doTask() {
}
}
-StatusWith<bool> ReplSetDistLockManager::canOvertakeLock(LocksType lockDoc,
+StatusWith<bool> ReplSetDistLockManager::canOvertakeLock(OperationContext* txn,
+ LocksType lockDoc,
const milliseconds& lockExpiration) {
const auto& processID = lockDoc.getProcess();
- auto pingStatus = _catalog->getPing(processID);
+ auto pingStatus = _catalog->getPing(txn, processID);
Date_t pingValue;
if (pingStatus.isOK()) {
@@ -173,7 +180,7 @@ StatusWith<bool> ReplSetDistLockManager::canOvertakeLock(LocksType lockDoc,
} // else use default pingValue if ping document does not exist.
Timer timer(_serviceContext->getTickSource());
- auto serverInfoStatus = _catalog->getServerInfo();
+ auto serverInfoStatus = _catalog->getServerInfo(txn);
if (!serverInfoStatus.isOK()) {
return serverInfoStatus.getStatus();
}
@@ -245,7 +252,11 @@ StatusWith<bool> ReplSetDistLockManager::canOvertakeLock(LocksType lockDoc,
}
StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
- StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) {
+ OperationContext* txn,
+ StringData name,
+ StringData whyMessage,
+ milliseconds waitFor,
+ milliseconds lockTryInterval) {
Timer timer(_serviceContext->getTickSource());
Timer msgTimer(_serviceContext->getTickSource());
@@ -264,8 +275,8 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
<< " ms, process : " << _processID << " )"
<< " with lockSessionID: " << lockSessionID << ", why: " << whyMessage;
- auto lockResult =
- _catalog->grabLock(name, lockSessionID, who, _processID, Date_t::now(), whyMessage);
+ auto lockResult = _catalog->grabLock(
+ txn, name, lockSessionID, who, _processID, Date_t::now(), whyMessage);
auto status = lockResult.getStatus();
@@ -274,7 +285,7 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
// the lock document.
LOG(0) << "distributed lock '" << name << "' acquired for '" << whyMessage
<< "', ts : " << lockSessionID;
- return ScopedDistLock(lockSessionID, this);
+ return ScopedDistLock(txn, lockSessionID, this);
}
if (status != ErrorCodes::LockStateChangeFailed) {
@@ -285,7 +296,7 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
}
// Get info from current lock and check if we can overtake it.
- auto getLockStatusResult = _catalog->getLockByName(name);
+ auto getLockStatusResult = _catalog->getLockByName(txn, name);
const auto& getLockStatus = getLockStatusResult.getStatus();
if (!getLockStatusResult.isOK() && getLockStatus != ErrorCodes::LockNotFound) {
@@ -296,14 +307,15 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
// found, use the normal grab lock path to acquire it.
if (getLockStatusResult.isOK()) {
auto currentLock = getLockStatusResult.getValue();
- auto canOvertakeResult = canOvertakeLock(currentLock, lockExpiration);
+ auto canOvertakeResult = canOvertakeLock(txn, currentLock, lockExpiration);
if (!canOvertakeResult.isOK()) {
return canOvertakeResult.getStatus();
}
if (canOvertakeResult.getValue()) {
- auto overtakeResult = _catalog->overtakeLock(name,
+ auto overtakeResult = _catalog->overtakeLock(txn,
+ name,
lockSessionID,
currentLock.getLockID(),
who,
@@ -319,7 +331,7 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
LOG(0) << "lock '" << name << "' successfully forced";
LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID;
- return ScopedDistLock(lockSessionID, this);
+ return ScopedDistLock(txn, lockSessionID, this);
}
if (overtakeStatus != ErrorCodes::LockStateChangeFailed) {
@@ -353,8 +365,8 @@ StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock(
return {ErrorCodes::LockBusy, str::stream() << "timed out waiting for " << name};
}
-void ReplSetDistLockManager::unlock(const DistLockHandle& lockSessionID) {
- auto unlockStatus = _catalog->unlock(lockSessionID);
+void ReplSetDistLockManager::unlock(OperationContext* txn, const DistLockHandle& lockSessionID) {
+ auto unlockStatus = _catalog->unlock(txn, lockSessionID);
if (!unlockStatus.isOK()) {
queueUnlock(lockSessionID);
@@ -364,8 +376,9 @@ void ReplSetDistLockManager::unlock(const DistLockHandle& lockSessionID) {
}
}
-Status ReplSetDistLockManager::checkStatus(const DistLockHandle& lockHandle) {
- return _catalog->getLockByTS(lockHandle).getStatus();
+Status ReplSetDistLockManager::checkStatus(OperationContext* txn,
+ const DistLockHandle& lockHandle) {
+ return _catalog->getLockByTS(txn, lockHandle).getStatus();
}
void ReplSetDistLockManager::queueUnlock(const DistLockHandle& lockSessionID) {
diff --git a/src/mongo/s/catalog/replset/replset_dist_lock_manager.h b/src/mongo/s/catalog/replset/replset_dist_lock_manager.h
index 273eee5f278..5d3024d58dc 100644
--- a/src/mongo/s/catalog/replset/replset_dist_lock_manager.h
+++ b/src/mongo/s/catalog/replset/replset_dist_lock_manager.h
@@ -61,18 +61,19 @@ public:
virtual ~ReplSetDistLockManager();
virtual void startUp() override;
- virtual void shutDown(bool allowNetworking) override;
+ virtual void shutDown(OperationContext* txn, bool allowNetworking) override;
virtual StatusWith<DistLockManager::ScopedDistLock> lock(
+ OperationContext* txn,
StringData name,
StringData whyMessage,
stdx::chrono::milliseconds waitFor,
stdx::chrono::milliseconds lockTryInterval) override;
protected:
- virtual void unlock(const DistLockHandle& lockSessionID) override;
+ virtual void unlock(OperationContext* txn, const DistLockHandle& lockSessionID) override;
- virtual Status checkStatus(const DistLockHandle& lockSessionID) override;
+ virtual Status checkStatus(OperationContext* txn, const DistLockHandle& lockSessionID) override;
private:
/**
@@ -94,7 +95,8 @@ private:
* Returns true if the current process that owns the lock has no fresh pings since
* the lock expiration threshold.
*/
- StatusWith<bool> canOvertakeLock(const LocksType lockDoc,
+ StatusWith<bool> canOvertakeLock(OperationContext* txn,
+ const LocksType lockDoc,
const stdx::chrono::milliseconds& lockExpiration);
//
diff --git a/src/mongo/s/catalog/replset/replset_dist_lock_manager_test.cpp b/src/mongo/s/catalog/replset/replset_dist_lock_manager_test.cpp
index 0b3a01c3ac3..9c940a06d07 100644
--- a/src/mongo/s/catalog/replset/replset_dist_lock_manager_test.cpp
+++ b/src/mongo/s/catalog/replset/replset_dist_lock_manager_test.cpp
@@ -40,6 +40,7 @@
#include "mongo/bson/json.h"
#include "mongo/bson/util/builder.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/service_context_noop.h"
#include "mongo/s/catalog/dist_lock_catalog_mock.h"
#include "mongo/s/catalog/type_lockpings.h"
@@ -79,14 +80,20 @@ public:
ReplSetDistLockManagerFixture()
: _dummyDoNotUse(stdx::make_unique<DistLockCatalogMock>()),
_mockCatalog(_dummyDoNotUse.get()),
- _processID("test"),
- _mgr(&_context, _processID, std::move(_dummyDoNotUse), kPingInterval, kLockExpiration) {}
+ _processID("test") {
+ setGlobalServiceContext(stdx::make_unique<ServiceContextNoop>());
+ _mgr = stdx::make_unique<ReplSetDistLockManager>(getGlobalServiceContext(),
+ _processID,
+ std::move(_dummyDoNotUse),
+ kPingInterval,
+ kLockExpiration);
+ }
/**
* Returns the lock manager instance that is being tested.
*/
ReplSetDistLockManager* getMgr() {
- return &_mgr;
+ return _mgr.get();
}
/**
@@ -103,23 +110,27 @@ public:
return _processID;
}
+ OperationContext* txn() {
+ return &_txn;
+ }
+
protected:
void setUp() override {
- _context.setTickSource(stdx::make_unique<SystemTickSource>());
- _mgr.startUp();
+ getGlobalServiceContext()->setTickSource(stdx::make_unique<SystemTickSource>());
+ _mgr->startUp();
}
void tearDown() override {
// Don't care about what shutDown passes to stopPing here.
_mockCatalog->expectStopPing([](StringData) {}, Status::OK());
- _mgr.shutDown(true);
+ _mgr->shutDown(txn(), true);
}
std::unique_ptr<DistLockCatalogMock> _dummyDoNotUse; // dummy placeholder
DistLockCatalogMock* _mockCatalog;
string _processID;
- ServiceContextNoop _context;
- ReplSetDistLockManager _mgr;
+ std::unique_ptr<ReplSetDistLockManager> _mgr;
+ OperationContextNoop _txn;
};
class RSDistLockMgrWithMockTickSource : public ReplSetDistLockManagerFixture {
@@ -128,13 +139,13 @@ public:
* Returns the mock tick source.
*/
TickSourceMock* getMockTickSource() {
- return dynamic_cast<TickSourceMock*>(_context.getTickSource());
+ return dynamic_cast<TickSourceMock*>(getGlobalServiceContext()->getTickSource());
}
protected:
void setUp() override {
- _context.setTickSource(stdx::make_unique<TickSourceMock>());
- _mgr.startUp();
+ getGlobalServiceContext()->setTickSource(stdx::make_unique<TickSourceMock>());
+ _mgr->startUp();
}
};
@@ -202,7 +213,8 @@ TEST_F(ReplSetDistLockManagerFixture, BasicLockLifeCycle) {
OID unlockSessionIDPassed;
{
- auto lockStatus = getMgr()->lock(lockName,
+ auto lockStatus = getMgr()->lock(txn(),
+ lockName,
whyMsg,
DistLockManager::kDefaultSingleLockAttemptTimeout,
DistLockManager::kDefaultLockRetryInterval);
@@ -334,7 +346,8 @@ TEST_F(RSDistLockMgrWithMockTickSource, LockSuccessAfterRetry) {
OID unlockSessionIDPassed;
{
- auto lockStatus = getMgr()->lock(lockName, whyMsg, Milliseconds(10), Milliseconds(1));
+ auto lockStatus =
+ getMgr()->lock(txn(), lockName, whyMsg, Milliseconds(10), Milliseconds(1));
ASSERT_OK(lockStatus.getStatus());
getMockCatalog()->expectNoGrabLock();
@@ -431,7 +444,8 @@ TEST_F(RSDistLockMgrWithMockTickSource, LockFailsAfterRetry) {
Status::OK());
{
- auto lockStatus = getMgr()->lock(lockName, whyMsg, Milliseconds(10), Milliseconds(1));
+ auto lockStatus =
+ getMgr()->lock(txn(), lockName, whyMsg, Milliseconds(10), Milliseconds(1));
ASSERT_NOT_OK(lockStatus.getStatus());
}
@@ -446,7 +460,7 @@ TEST_F(RSDistLockMgrWithMockTickSource, LockFailsAfterRetry) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -469,7 +483,7 @@ TEST_F(ReplSetDistLockManagerFixture, LockBusyNoRetry) {
getMockCatalog()->expectGetLockByName([](StringData) {},
{ErrorCodes::LockNotFound, "not found!"});
- auto status = getMgr()->lock("", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -518,7 +532,7 @@ TEST_F(RSDistLockMgrWithMockTickSource, LockRetryTimeout) {
{ErrorCodes::LockNotFound, "not found!"});
auto lockStatus =
- getMgr()->lock(lockName, whyMsg, Milliseconds(5), Milliseconds(1)).getStatus();
+ getMgr()->lock(txn(), lockName, whyMsg, Milliseconds(5), Milliseconds(1)).getStatus();
ASSERT_NOT_OK(lockStatus);
ASSERT_EQUALS(ErrorCodes::LockBusy, lockStatus.code());
@@ -572,7 +586,7 @@ TEST_F(ReplSetDistLockManagerFixture, MustUnlockOnLockError) {
Status::OK());
auto lockStatus =
- getMgr()->lock(lockName, whyMsg, Milliseconds(10), Milliseconds(1)).getStatus();
+ getMgr()->lock(txn(), lockName, whyMsg, Milliseconds(10), Milliseconds(1)).getStatus();
ASSERT_NOT_OK(lockStatus);
ASSERT_EQUALS(ErrorCodes::NetworkTimeout, lockStatus.code());
@@ -587,7 +601,7 @@ TEST_F(ReplSetDistLockManagerFixture, MustUnlockOnLockError) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -637,7 +651,7 @@ TEST_F(ReplSetDistLockManagerFixture, LockPinging) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -707,7 +721,7 @@ TEST_F(ReplSetDistLockManagerFixture, UnlockUntilNoError) {
StringData why) { lockSessionID = lockSessionIDArg; },
retLockDoc);
- { auto lockStatus = getMgr()->lock("test", "why", Milliseconds(0), Milliseconds(0)); }
+ { auto lockStatus = getMgr()->lock(txn(), "test", "why", Milliseconds(0), Milliseconds(0)); }
bool didTimeout = false;
{
@@ -720,7 +734,7 @@ TEST_F(ReplSetDistLockManagerFixture, UnlockUntilNoError) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -800,8 +814,8 @@ TEST_F(ReplSetDistLockManagerFixture, MultipleQueuedUnlock) {
retLockDoc);
{
- auto lockStatus = getMgr()->lock("test", "why", Milliseconds(0), Milliseconds(0));
- auto otherStatus = getMgr()->lock("lock", "why", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "test", "why", Milliseconds(0), Milliseconds(0));
+ auto otherStatus = getMgr()->lock(txn(), "lock", "why", Milliseconds(0), Milliseconds(0));
}
bool didTimeout = false;
@@ -816,7 +830,7 @@ TEST_F(ReplSetDistLockManagerFixture, MultipleQueuedUnlock) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -840,7 +854,7 @@ TEST_F(ReplSetDistLockManagerFixture, CleanupPingOnShutdown) {
stopPingCalled = true;
}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
ASSERT_TRUE(stopPingCalled);
}
@@ -863,7 +877,7 @@ TEST_F(ReplSetDistLockManagerFixture, CheckLockStatusOK) {
retLockDoc);
- auto lockStatus = getMgr()->lock("a", "", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "a", "", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
getMockCatalog()->expectNoGrabLock();
@@ -901,7 +915,7 @@ TEST_F(ReplSetDistLockManagerFixture, CheckLockStatusNoLongerOwn) {
retLockDoc);
- auto lockStatus = getMgr()->lock("a", "", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "a", "", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
getMockCatalog()->expectNoGrabLock();
@@ -940,7 +954,7 @@ TEST_F(ReplSetDistLockManagerFixture, CheckLockStatusError) {
retLockDoc);
- auto lockStatus = getMgr()->lock("a", "", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "a", "", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
getMockCatalog()->expectNoGrabLock();
@@ -1002,7 +1016,8 @@ TEST_F(ReplSetDistLockManagerFixture, BasicLockOvertaking) {
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1032,7 +1047,7 @@ TEST_F(ReplSetDistLockManagerFixture, BasicLockOvertaking) {
// Second attempt should overtake lock.
{
- auto lockStatus = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
@@ -1078,7 +1093,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfExpirationHasNotElapsed) {
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1089,7 +1105,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfExpirationHasNotElapsed) {
// Second attempt should still not overtake lock.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1117,7 +1134,7 @@ TEST_F(ReplSetDistLockManagerFixture, GetPingErrorWhileOvertaking) {
ASSERT_EQUALS("otherProcess", process);
}, {ErrorCodes::NetworkTimeout, "bad test network"});
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::NetworkTimeout, status.code());
}
@@ -1144,7 +1161,7 @@ TEST_F(ReplSetDistLockManagerFixture, GetInvalidPingDocumentWhileOvertaking) {
getMockCatalog()->expectGetPing(
[](StringData process) { ASSERT_EQUALS("otherProcess", process); }, invalidPing);
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, status.code());
}
@@ -1177,7 +1194,7 @@ TEST_F(ReplSetDistLockManagerFixture, GetServerInfoErrorWhileOvertaking) {
getMockCatalog()->expectGetServerInfo([]() {},
{ErrorCodes::NetworkTimeout, "bad test network"});
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::NetworkTimeout, status.code());
}
@@ -1192,7 +1209,7 @@ TEST_F(ReplSetDistLockManagerFixture, GetLockErrorWhileOvertaking) {
getMockCatalog()->expectGetLockByName([](StringData name) { ASSERT_EQUALS("bar", name); },
{ErrorCodes::NetworkTimeout, "bad test network"});
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::NetworkTimeout, status.code());
}
@@ -1207,7 +1224,7 @@ TEST_F(ReplSetDistLockManagerFixture, GetLockDisappearedWhileOvertaking) {
getMockCatalog()->expectGetLockByName([](StringData name) { ASSERT_EQUALS("bar", name); },
{ErrorCodes::LockNotFound, "disappeared!"});
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status = getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1259,7 +1276,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfPingIsActive) {
getServerInfoCallCount++;
}, DistLockCatalog::ServerInfo(configServerLocalTime, OID()));
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1293,7 +1311,7 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfPingIsActive) {
OID unlockSessionIDPassed;
{
- auto lockStatus = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
@@ -1357,7 +1375,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfOwnerJustChanged) {
getServerInfoCallCount++;
}, DistLockCatalog::ServerInfo(configServerLocalTime, OID()));
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1391,7 +1410,7 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfOwnerJustChanged) {
OID unlockSessionIDPassed;
{
- auto lockStatus = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
@@ -1458,7 +1477,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfElectionIdChanged) {
getServerInfoCallCount++;
}, DistLockCatalog::ServerInfo(configServerLocalTime, lastElectionId));
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1492,7 +1512,7 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfElectionIdChanged) {
OID unlockSessionIDPassed;
{
- auto lockStatus = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0));
ASSERT_OK(lockStatus.getStatus());
@@ -1550,7 +1570,8 @@ TEST_F(ReplSetDistLockManagerFixture, LockOvertakingResultsInError) {
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1589,7 +1610,7 @@ TEST_F(ReplSetDistLockManagerFixture, LockOvertakingResultsInError) {
Status::OK());
// Second attempt should overtake lock.
- auto lockStatus = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0));
+ auto lockStatus = getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0));
ASSERT_NOT_OK(lockStatus.getStatus());
@@ -1604,7 +1625,7 @@ TEST_F(ReplSetDistLockManagerFixture, LockOvertakingResultsInError) {
// Join the background thread before trying to call asserts. Shutdown calls
// stopPing and we don't care in this test.
getMockCatalog()->expectStopPing([](StringData) {}, Status::OK());
- getMgr()->shutDown(true);
+ getMgr()->shutDown(txn(), true);
// No assert until shutDown has been called to make sure that the background thread
// won't be trying to access the local variables that were captured by lamdas that
@@ -1655,7 +1676,8 @@ TEST_F(ReplSetDistLockManagerFixture, LockOvertakingFailed) {
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1681,7 +1703,8 @@ TEST_F(ReplSetDistLockManagerFixture, LockOvertakingFailed) {
{ErrorCodes::LockStateChangeFailed, "nmod 0"});
{
- auto status = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1728,7 +1751,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfConfigServerClockGoesBackw
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1739,7 +1763,8 @@ TEST_F(ReplSetDistLockManagerFixture, CannotOvertakeIfConfigServerClockGoesBackw
// Second attempt should not overtake lock.
{
- auto status = getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1781,7 +1806,8 @@ TEST_F(RSDistLockMgrWithMockTickSource, CanOvertakeIfNoPingDocument) {
// First attempt will record the ping data.
{
- auto status = getMgr()->lock("bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
+ auto status =
+ getMgr()->lock(txn(), "bar", "", Milliseconds(0), Milliseconds(0)).getStatus();
ASSERT_NOT_OK(status);
ASSERT_EQUALS(ErrorCodes::LockBusy, status.code());
}
@@ -1826,7 +1852,10 @@ TEST_F(RSDistLockMgrWithMockTickSource, CanOvertakeIfNoPingDocument) {
Status::OK());
// Second attempt should overtake lock.
- { ASSERT_OK(getMgr()->lock("bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus()); }
+ {
+ ASSERT_OK(
+ getMgr()->lock(txn(), "bar", "foo", Milliseconds(0), Milliseconds(0)).getStatus());
+ }
}
} // unnamed namespace
diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp
index 3d0c7725184..99df3d845b2 100644
--- a/src/mongo/s/client/shard_registry.cpp
+++ b/src/mongo/s/client/shard_registry.cpp
@@ -34,12 +34,14 @@
#include <set>
+#include "mongo/bson/bsonobj.h"
#include "mongo/client/connection_string.h"
#include "mongo/client/query_fetcher.h"
#include "mongo/client/remote_command_targeter.h"
#include "mongo/client/remote_command_targeter_factory.h"
#include "mongo/client/replica_set_monitor.h"
#include "mongo/db/client.h"
+#include "mongo/db/query/lite_parsed_query.h"
#include "mongo/executor/task_executor.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/rpc/metadata/config_server_metadata.h"
@@ -54,6 +56,7 @@
#include "mongo/stdx/mutex.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
+#include "mongo/util/time_support.h"
namespace mongo {
@@ -86,6 +89,39 @@ void updateReplSetMonitor(const std::shared_ptr<RemoteCommandTargeter>& targeter
}
}
+BSONObj appendMaxTimeToCmdObj(long long maxTimeMicros, const BSONObj& cmdObj) {
+ Seconds maxTime = kConfigCommandTimeout;
+
+ Microseconds remainingTxnMaxTime(maxTimeMicros);
+ bool hasTxnMaxTime(remainingTxnMaxTime != Microseconds::zero());
+ bool hasUserMaxTime = !cmdObj[LiteParsedQuery::cmdOptionMaxTimeMS].eoo();
+
+ if (hasTxnMaxTime) {
+ maxTime = duration_cast<Seconds>(remainingTxnMaxTime);
+ } else if (hasUserMaxTime) {
+ return cmdObj;
+ }
+
+ BSONObjBuilder updatedCmdBuilder;
+ if (hasTxnMaxTime && hasUserMaxTime) { // Need to remove user provided maxTimeMS.
+ BSONObjIterator cmdObjIter(cmdObj);
+ const char* maxTimeFieldName = LiteParsedQuery::cmdOptionMaxTimeMS.c_str();
+ while (cmdObjIter.more()) {
+ BSONElement e = cmdObjIter.next();
+ if (str::equals(e.fieldName(), maxTimeFieldName)) {
+ continue;
+ }
+ updatedCmdBuilder.append(e);
+ }
+ } else {
+ updatedCmdBuilder.appendElements(cmdObj);
+ }
+
+ updatedCmdBuilder.append(LiteParsedQuery::cmdOptionMaxTimeMS,
+ durationCount<Milliseconds>(maxTime));
+ return updatedCmdBuilder.obj();
+}
+
} // unnamed namespace
ShardRegistry::ShardRegistry(std::unique_ptr<RemoteCommandTargeterFactory> targeterFactory,
@@ -352,6 +388,7 @@ OpTime ShardRegistry::getConfigOpTime() {
}
StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfig(
+ OperationContext* txn,
const ReadPreferenceSetting& readPref,
const NamespaceString& nss,
const BSONObj& query,
@@ -419,6 +456,14 @@ StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfig(
BSONObjBuilder findCmdBuilder;
lpq->asFindCommand(&findCmdBuilder);
+ Seconds maxTime = kConfigCommandTimeout;
+ Microseconds remainingTxnMaxTime(txn->getRemainingMaxTimeMicros());
+ if (remainingTxnMaxTime != Microseconds::zero()) {
+ maxTime = duration_cast<Seconds>(remainingTxnMaxTime);
+ }
+ findCmdBuilder.append(LiteParsedQuery::cmdOptionMaxTimeMS,
+ durationCount<Milliseconds>(maxTime));
+
QueryFetcher fetcher(_executor.get(),
host.getValue(),
nss,
@@ -498,7 +543,8 @@ StatusWith<BSONObj> ShardRegistry::runCommandForAddShard(OperationContext* txn,
return status.getValue().response;
}
-StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const ReadPreferenceSetting& readPref,
+StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(OperationContext* txn,
+ const ReadPreferenceSetting& readPref,
const std::string& dbName,
const BSONObj& cmdObj) {
auto response = _runCommandWithMetadata(
@@ -506,7 +552,7 @@ StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const ReadPreferenceSettin
getConfigShard(),
readPref,
dbName,
- cmdObj,
+ appendMaxTimeToCmdObj(txn->getRemainingMaxTimeMicros(), cmdObj),
readPref.pref == ReadPreference::PrimaryOnly ? kReplMetadata : kReplSecondaryOkMetadata);
if (!response.isOK()) {
@@ -517,10 +563,15 @@ StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const ReadPreferenceSettin
return response.getValue().response;
}
-StatusWith<BSONObj> ShardRegistry::runCommandOnConfigWithNotMasterRetries(const std::string& dbname,
+StatusWith<BSONObj> ShardRegistry::runCommandOnConfigWithNotMasterRetries(OperationContext* txn,
+ const std::string& dbname,
const BSONObj& cmdObj) {
auto response = _runCommandWithNotMasterRetries(
- _executor.get(), getConfigShard(), dbname, cmdObj, kReplMetadata);
+ _executor.get(),
+ getConfigShard(),
+ dbname,
+ appendMaxTimeToCmdObj(txn->getRemainingMaxTimeMicros(), cmdObj),
+ kReplMetadata);
if (!response.isOK()) {
return response.getStatus();
diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h
index f09ed9bd54a..27efbb16488 100644
--- a/src/mongo/s/client/shard_registry.h
+++ b/src/mongo/s/client/shard_registry.h
@@ -201,6 +201,7 @@ public:
* Note: should never be used outside of CatalogManagerReplicaSet or DistLockCatalogImpl.
*/
StatusWith<QueryResponse> exhaustiveFindOnConfig(
+ OperationContext* txn,
const ReadPreferenceSetting& readPref,
const NamespaceString& nss,
const BSONObj& query,
@@ -240,7 +241,8 @@ public:
* the result. It is the responsibility of the caller to check the returned BSON for
* command-specific failures.
*/
- StatusWith<BSONObj> runCommandOnConfig(const ReadPreferenceSetting& readPref,
+ StatusWith<BSONObj> runCommandOnConfig(OperationContext* txn,
+ const ReadPreferenceSetting& readPref,
const std::string& dbname,
const BSONObj& cmdObj);
@@ -260,7 +262,8 @@ public:
const std::string& dbname,
const BSONObj& cmdObj);
- StatusWith<BSONObj> runCommandOnConfigWithNotMasterRetries(const std::string& dbname,
+ StatusWith<BSONObj> runCommandOnConfigWithNotMasterRetries(OperationContext* txn,
+ const std::string& dbname,
const BSONObj& cmdObj);
private: