summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-06-24 15:26:18 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-06-27 09:56:58 -0400
commit8fe4426fa36587ca40a0b6c8f1c84fd9aa61e5cf (patch)
tree80441172024fa0d6e752e5766aacbbce8f706703
parentb7f7d746eba8ec30d059352c811e9ac57618b3bd (diff)
downloadmongo-8fe4426fa36587ca40a0b6c8f1c84fd9aa61e5cf.tar.gz
SERVER-29852 Store session id and transaction number on all commands' OperationContext
-rw-r--r--src/mongo/bson/ugly_bson_integration_test.cpp2
-rw-r--r--src/mongo/db/client.cpp5
-rw-r--r--src/mongo/db/client.h4
-rw-r--r--src/mongo/db/exec/queued_data_stage_test.cpp8
-rw-r--r--src/mongo/db/exec/sort_test.cpp8
-rw-r--r--src/mongo/db/logical_session_id.cpp7
-rw-r--r--src/mongo/db/logical_session_id.h9
-rw-r--r--src/mongo/db/logical_session_id.idl14
-rw-r--r--src/mongo/db/operation_context.cpp37
-rw-r--r--src/mongo/db/operation_context.h33
-rw-r--r--src/mongo/db/operation_context_noop.h8
-rw-r--r--src/mongo/db/operation_context_test.cpp116
-rw-r--r--src/mongo/db/query/query_test_service_context.cpp5
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.cpp11
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.h4
-rw-r--r--src/mongo/db/service_context.cpp8
-rw-r--r--src/mongo/db/service_context.h12
-rw-r--r--src/mongo/db/service_context_d.cpp5
-rw-r--r--src/mongo/db/service_context_d.h5
-rw-r--r--src/mongo/db/service_context_noop.cpp9
-rw-r--r--src/mongo/db/service_context_noop.h9
-rw-r--r--src/mongo/db/service_entry_point_mongod.cpp3
-rw-r--r--src/mongo/s/commands/strategy.cpp2
23 files changed, 218 insertions, 106 deletions
diff --git a/src/mongo/bson/ugly_bson_integration_test.cpp b/src/mongo/bson/ugly_bson_integration_test.cpp
index baa53cc5051..5cf99f07bda 100644
--- a/src/mongo/bson/ugly_bson_integration_test.cpp
+++ b/src/mongo/bson/ugly_bson_integration_test.cpp
@@ -60,7 +60,7 @@ TEST_F(UglyBSONFixture, DuplicateFields) {
<< BSONArray()
<< "documents"
<< BSONArray()),
- ErrorCodes::FailedToParse);
+ ErrorCodes::fromInt(40413));
}
} // namespace
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 6ecfeb3195b..ac195c79606 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -123,9 +123,8 @@ void Client::reportState(BSONObjBuilder& builder) {
}
}
-ServiceContext::UniqueOperationContext Client::makeOperationContext(
- boost::optional<LogicalSessionId> lsid) {
- return getServiceContext()->makeOperationContext(this, std::move(lsid));
+ServiceContext::UniqueOperationContext Client::makeOperationContext() {
+ return getServiceContext()->makeOperationContext(this);
}
void Client::setOperationContext(OperationContext* opCtx) {
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index a4f263f7d92..3ceb236c2dc 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -40,7 +40,6 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/db/client.h"
-#include "mongo/db/logical_session_id.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/service_context.h"
#include "mongo/platform/random.h"
@@ -173,8 +172,7 @@ public:
*
* If provided, the LogicalSessionId links this operation to a logical session.
*/
- ServiceContext::UniqueOperationContext makeOperationContext(
- boost::optional<LogicalSessionId> lsid = boost::none);
+ ServiceContext::UniqueOperationContext makeOperationContext();
/**
* Sets the active operation context on this client to "opCtx", which must be non-NULL.
diff --git a/src/mongo/db/exec/queued_data_stage_test.cpp b/src/mongo/db/exec/queued_data_stage_test.cpp
index 08a2a57569d..960d832777a 100644
--- a/src/mongo/db/exec/queued_data_stage_test.cpp
+++ b/src/mongo/db/exec/queued_data_stage_test.cpp
@@ -53,9 +53,9 @@ class QueuedDataStageTest : public unittest::Test {
public:
QueuedDataStageTest() {
_service = stdx::make_unique<ServiceContextNoop>();
- _service.get()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
- _client = _service.get()->makeClient("test");
- _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0, boost::none));
+ _service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
+ _client = _service->makeClient("test");
+ _opCtxNoop = _client->makeOperationContext();
_opCtx = _opCtxNoop.get();
}
@@ -72,7 +72,7 @@ private:
// The OperationContextNoop must be destroyed before the UniqueClient is destroyed.
std::unique_ptr<ServiceContextNoop> _service;
ServiceContext::UniqueClient _client;
- std::unique_ptr<OperationContextNoop> _opCtxNoop;
+ ServiceContext::UniqueOperationContext _opCtxNoop;
};
//
diff --git a/src/mongo/db/exec/sort_test.cpp b/src/mongo/db/exec/sort_test.cpp
index 68a2240db7b..08f3f15580e 100644
--- a/src/mongo/db/exec/sort_test.cpp
+++ b/src/mongo/db/exec/sort_test.cpp
@@ -53,9 +53,9 @@ class SortStageTest : public unittest::Test {
public:
SortStageTest() {
_service = stdx::make_unique<ServiceContextNoop>();
- _service.get()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
- _client = _service.get()->makeClient("test");
- _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0, boost::none));
+ _service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
+ _client = _service->makeClient("test");
+ _opCtxNoop = _client->makeOperationContext();
_opCtx = _opCtxNoop.get();
CollatorFactoryInterface::set(_service.get(), stdx::make_unique<CollatorFactoryMock>());
}
@@ -163,7 +163,7 @@ private:
// The UniqueClient must be destroyed before the ServiceContextNoop is destroyed.
// The OperationContextNoop must be destroyed before the UniqueClient is destroyed.
ServiceContext::UniqueClient _client;
- std::unique_ptr<OperationContextNoop> _opCtxNoop;
+ ServiceContext::UniqueOperationContext _opCtxNoop;
};
TEST_F(SortStageTest, SortEmptyWorkingSet) {
diff --git a/src/mongo/db/logical_session_id.cpp b/src/mongo/db/logical_session_id.cpp
index 497036a9d6c..36e4c6faf58 100644
--- a/src/mongo/db/logical_session_id.cpp
+++ b/src/mongo/db/logical_session_id.cpp
@@ -31,13 +31,14 @@
#include "mongo/db/logical_session_id.h"
#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/db/logical_session_id_gen.h"
#include "mongo/util/assert_util.h"
namespace mongo {
-LogicalSessionId::LogicalSessionId() {
- setId(UUID::gen());
+LogicalSessionId::LogicalSessionId() : LogicalSessionId(UUID::gen()) {}
+
+LogicalSessionId::LogicalSessionId(Logical_session_id&& lsid) {
+ static_cast<Logical_session_id&>(*this) = lsid;
}
LogicalSessionId::LogicalSessionId(UUID id) {
diff --git a/src/mongo/db/logical_session_id.h b/src/mongo/db/logical_session_id.h
index fe95cf51000..979f2bcc585 100644
--- a/src/mongo/db/logical_session_id.h
+++ b/src/mongo/db/logical_session_id.h
@@ -49,8 +49,8 @@ class BSONObjBuilder;
*/
class LogicalSessionId : public Logical_session_id {
public:
- friend class Logical_session_id;
- friend class Logical_session_record;
+ LogicalSessionId();
+ LogicalSessionId(Logical_session_id&& lsid);
/**
* Create and return a new LogicalSessionId with a random UUID.
@@ -100,11 +100,6 @@ public:
UUID::Hash _hasher;
};
- /**
- * This constructor exists for IDL only.
- */
- LogicalSessionId();
-
private:
/**
* Construct a LogicalSessionId from a UUID.
diff --git a/src/mongo/db/logical_session_id.idl b/src/mongo/db/logical_session_id.idl
index a88fcddd0c7..2f02ea2a06a 100644
--- a/src/mongo/db/logical_session_id.idl
+++ b/src/mongo/db/logical_session_id.idl
@@ -55,3 +55,17 @@ structs:
strict: true
fields:
id: UUIDIDL
+
+ OperationSessionInfo:
+ description: "Parser for pulling out the sessionId/txnNumber combination from commands"
+ strict: false
+ fields:
+ lsid:
+ type: logical_session_id
+ cpp_name: sessionId
+ optional: true
+ txnNumber:
+ description: "The transaction number relative to the session in which a particular write
+ operation executes."
+ type: TxnNumber
+ optional: true
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
index b185185876b..c72d1990f3c 100644
--- a/src/mongo/db/operation_context.cpp
+++ b/src/mongo/db/operation_context.cpp
@@ -75,12 +75,9 @@ MONGO_FP_DECLARE(checkForInterruptFail);
} // namespace
-OperationContext::OperationContext(Client* client,
- unsigned int opId,
- boost::optional<LogicalSessionId> lsid)
+OperationContext::OperationContext(Client* client, unsigned int opId)
: _client(client),
_opId(opId),
- _lsid(std::move(lsid)),
_elapsedTime(client ? client->getServiceContext()->getTickSource()
: SystemTickSource::get()) {}
@@ -348,6 +345,17 @@ void OperationContext::markKilled(ErrorCodes::Error killCode) {
}
}
+void OperationContext::setLogicalSessionId(LogicalSessionId lsid) {
+ invariant(!_lsid);
+ _lsid = std::move(lsid);
+}
+
+void OperationContext::setTxnNumber(TxnNumber txnNumber) {
+ invariant(_lsid);
+ invariant(!_txnNumber);
+ _txnNumber = txnNumber;
+}
+
RecoveryUnit* OperationContext::releaseRecoveryUnit() {
return _recoveryUnit.release();
}
@@ -375,4 +383,25 @@ Date_t OperationContext::getExpirationDateForWaitForValue(Milliseconds waitFor)
return getServiceContext()->getPreciseClockSource()->now() + waitFor;
}
+void initializeOperationSessionInfo(OperationContext* opCtx, const BSONObj& requestBody) {
+ auto osi =
+ OperationSessionInfo::parse(IDLParserErrorContext("OperationSessionInfo"), requestBody);
+
+ if (osi.getSessionId()) {
+ auto lsid = *osi.getSessionId();
+ opCtx->setLogicalSessionId(LogicalSessionId(std::move(lsid)));
+ }
+
+ if (osi.getTxnNumber()) {
+ uassert(ErrorCodes::IllegalOperation,
+ "Transaction number requires a sessionId to be specified",
+ opCtx->getLogicalSessionId());
+ uassert(ErrorCodes::BadValue,
+ "Transaction number cannot be negative",
+ *osi.getTxnNumber() >= 0);
+
+ opCtx->setTxnNumber(*osi.getTxnNumber());
+ }
+}
+
} // namespace mongo
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 4e859efa67f..9bacdde641c 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -84,7 +84,7 @@ public:
kFailedUnitOfWork // in a unit of work that has failed and must be aborted
};
- OperationContext(Client* client, unsigned int opId, boost::optional<LogicalSessionId> lsid);
+ OperationContext(Client* client, unsigned int opId);
virtual ~OperationContext() = default;
@@ -268,6 +268,26 @@ public:
}
/**
+ * Associates a logical session id with this operation context. May only be called once for the
+ * lifetime of the operation.
+ */
+ void setLogicalSessionId(LogicalSessionId lsid);
+
+ /**
+ * Returns the transaction number associated with thes operation. The combination of logical
+ * session id + transaction number is what constitutes the operation transaction id.
+ */
+ boost::optional<TxnNumber> getTxnNumber() const {
+ return _txnNumber;
+ }
+
+ /**
+ * Associates a transaction number with this operation context. May only be called once for the
+ * lifetime of the operation and the operation must have a logical session id assigned.
+ */
+ void setTxnNumber(TxnNumber txnNumber);
+
+ /**
* Returns WriteConcernOptions of the current operation
*/
const WriteConcernOptions& getWriteConcern() const {
@@ -408,7 +428,9 @@ private:
friend class repl::UnreplicatedWritesBlock;
Client* const _client;
const unsigned int _opId;
+
boost::optional<LogicalSessionId> _lsid;
+ boost::optional<TxnNumber> _txnNumber;
std::unique_ptr<Locker> _locker;
@@ -526,4 +548,13 @@ private:
};
} // namespace repl
+/**
+ * Parses the session information from the body of a request and installs it on the current
+ * operation context. Must only be called once per operation and should be done right in the
+ * beginning.
+ *
+ * Throws if the sessionId/txnNumber combination is not properly formatted.
+ */
+void initializeOperationSessionInfo(OperationContext* opCtx, const BSONObj& requestBody);
+
} // namespace mongo
diff --git a/src/mongo/db/operation_context_noop.h b/src/mongo/db/operation_context_noop.h
index c9b2a0df134..071d80b8893 100644
--- a/src/mongo/db/operation_context_noop.h
+++ b/src/mongo/db/operation_context_noop.h
@@ -46,17 +46,15 @@ public:
* These constructors are for use in legacy tests that do not need operation contexts that are
* properly connected to clients.
*/
- OperationContextNoop() : OperationContextNoop(nullptr, 0, boost::none) {}
- OperationContextNoop(RecoveryUnit* ru) : OperationContextNoop(nullptr, 0, boost::none) {
+ OperationContextNoop() : OperationContextNoop(nullptr, 0) {}
+ OperationContextNoop(RecoveryUnit* ru) : OperationContextNoop(nullptr, 0) {
setRecoveryUnit(ru, kNotInUnitOfWork);
}
-
/**
* This constructor is for use by ServiceContexts, and should not be called directly.
*/
- OperationContextNoop(Client* client, unsigned int opId, boost::optional<LogicalSessionId> lsid)
- : OperationContext(client, opId, std::move(lsid)) {
+ OperationContextNoop(Client* client, unsigned int opId) : OperationContext(client, opId) {
setRecoveryUnit(new RecoveryUnitNoop(), kNotInUnitOfWork);
setLockState(stdx::make_unique<LockerNoop>());
}
diff --git a/src/mongo/db/operation_context_test.cpp b/src/mongo/db/operation_context_test.cpp
index 33e23f45593..4a6117dbeea 100644
--- a/src/mongo/db/operation_context_test.cpp
+++ b/src/mongo/db/operation_context_test.cpp
@@ -31,6 +31,7 @@
#include <boost/optional.hpp>
#include "mongo/db/client.h"
+#include "mongo/db/json.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
@@ -45,9 +46,10 @@
#include "mongo/util/time_support.h"
namespace mongo {
-
namespace {
+using unittest::assertGet;
+
std::ostream& operator<<(std::ostream& os, stdx::cv_status cvStatus) {
switch (cvStatus) {
case stdx::cv_status::timeout:
@@ -72,38 +74,100 @@ std::ostream& operator<<(std::ostream& os, stdx::future_status futureStatus) {
}
}
-TEST(OperationContextTest, CanHaveLogicalSessionId) {
- // Test that we can create opCtx's with or without a logical session id
+TEST(OperationContextTest, NoSessionIdNoTransactionNumber) {
auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
- // No session id
- {
- auto opCtx = client->makeOperationContext();
- ASSERT(!opCtx->getLogicalSessionId());
- }
+ ASSERT(!opCtx->getLogicalSessionId());
+ ASSERT(!opCtx->getTxnNumber());
+}
- {
- auto opCtx = serviceCtx->makeOperationContext(client.get());
- ASSERT(!opCtx->getLogicalSessionId());
- }
+TEST(OperationContextTest, SessionIdNoTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
- // With a session id
- auto res = LogicalSessionId::parse("00000000-abab-4000-8000-000000000000");
- ASSERT(res.isOK());
- auto lsid = res.getValue();
+ const auto lsid = assertGet(LogicalSessionId::parse("00000000-abab-4000-8000-000000000000"));
+ opCtx->setLogicalSessionId(lsid);
- {
- auto opCtx = client->makeOperationContext(lsid);
- ASSERT(opCtx->getLogicalSessionId());
- ASSERT_EQUALS(*(opCtx->getLogicalSessionId()), lsid);
- }
+ ASSERT(opCtx->getLogicalSessionId());
+ ASSERT_EQUALS(lsid, *opCtx->getLogicalSessionId());
- {
- auto opCtx = serviceCtx->makeOperationContext(client.get(), lsid);
- ASSERT(opCtx->getLogicalSessionId());
- ASSERT_EQUALS(*(opCtx->getLogicalSessionId()), lsid);
- }
+ ASSERT(!opCtx->getTxnNumber());
+}
+
+TEST(OperationContextTest, SessionIdAndTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
+
+ const auto lsid = assertGet(LogicalSessionId::parse("00000000-abab-4000-8000-000000000000"));
+ opCtx->setLogicalSessionId(lsid);
+ opCtx->setTxnNumber(5);
+
+ ASSERT(opCtx->getTxnNumber());
+ ASSERT_EQUALS(5, *opCtx->getTxnNumber());
+}
+
+TEST(OperationContextTest, InitializeOperationSessionInfo_NoSessionIdNoTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
+
+ initializeOperationSessionInfo(opCtx.get(), BSON("TestCmd" << 1));
+
+ ASSERT(!opCtx->getLogicalSessionId());
+ ASSERT(!opCtx->getTxnNumber());
+}
+
+TEST(OperationContextTest, InitializeOperationSessionInfo_SessionIdNoTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
+
+ LogicalSessionId lsid;
+
+ initializeOperationSessionInfo(opCtx.get(),
+ BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "OtherField"
+ << "TestField"));
+
+ ASSERT(opCtx->getLogicalSessionId());
+ ASSERT_EQ(lsid, *opCtx->getLogicalSessionId());
+
+ ASSERT(!opCtx->getTxnNumber());
+}
+
+TEST(OperationContextTest, InitializeOperationSessionInfo_MissingSessionIdWithTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
+
+ ASSERT_THROWS_CODE(
+ initializeOperationSessionInfo(opCtx.get(),
+ BSON("TestCmd" << 1 << "txnNumber" << 100LL << "OtherField"
+ << "TestField")),
+ UserException,
+ ErrorCodes::IllegalOperation);
+}
+
+TEST(OperationContextTest, InitializeOperationSessionInfo_SessionIdAndTransactionNumber) {
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+ auto opCtx = client->makeOperationContext();
+
+ LogicalSessionId lsid;
+
+ initializeOperationSessionInfo(
+ opCtx.get(),
+ BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "txnNumber" << 100LL << "OtherField"
+ << "TestField"));
+
+ ASSERT(opCtx->getLogicalSessionId());
+ ASSERT_EQ(lsid, *opCtx->getLogicalSessionId());
+
+ ASSERT(opCtx->getTxnNumber());
+ ASSERT_EQ(100, *opCtx->getTxnNumber());
}
class OperationDeadlineTests : public unittest::Test {
diff --git a/src/mongo/db/query/query_test_service_context.cpp b/src/mongo/db/query/query_test_service_context.cpp
index 4ad6ac8e857..d752db15664 100644
--- a/src/mongo/db/query/query_test_service_context.cpp
+++ b/src/mongo/db/query/query_test_service_context.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/query/query_test_service_context.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/query/collation/collator_factory_mock.h"
#include "mongo/stdx/memory.h"
@@ -46,7 +47,9 @@ ServiceContext::UniqueOperationContext QueryTestServiceContext::makeOperationCon
ServiceContext::UniqueOperationContext QueryTestServiceContext::makeOperationContext(
LogicalSessionId lsid) {
- return _uniqueClient->makeOperationContext(std::move(lsid));
+ auto opCtx = makeOperationContext();
+ opCtx->setLogicalSessionId(lsid);
+ return opCtx;
}
Client* QueryTestServiceContext::getClient() const {
diff --git a/src/mongo/db/repl/service_context_repl_mock.cpp b/src/mongo/db/repl/service_context_repl_mock.cpp
index f411a45bfc7..31dcf83c3ba 100644
--- a/src/mongo/db/repl/service_context_repl_mock.cpp
+++ b/src/mongo/db/repl/service_context_repl_mock.cpp
@@ -30,23 +30,18 @@
#include "mongo/db/repl/service_context_repl_mock.h"
-#include <boost/optional.hpp>
-#include <memory>
-
#include "mongo/db/concurrency/lock_state.h"
-#include "mongo/db/concurrency/locker.h"
#include "mongo/db/operation_context_noop.h"
#include "mongo/stdx/memory.h"
namespace mongo {
namespace repl {
-std::unique_ptr<OperationContext> ServiceContextReplMock::_newOpCtx(
- Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid) {
- auto opCtx = stdx::make_unique<OperationContextNoop>(client, opId, std::move(lsid));
+std::unique_ptr<OperationContext> ServiceContextReplMock::_newOpCtx(Client* client, unsigned opId) {
+ auto opCtx = stdx::make_unique<OperationContextNoop>(client, opId);
opCtx->releaseLockState();
opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
- return std::move(opCtx);
+ return {std::move(opCtx)};
}
} // namespace repl
diff --git a/src/mongo/db/repl/service_context_repl_mock.h b/src/mongo/db/repl/service_context_repl_mock.h
index dfc68a020d7..8ffb92a9da1 100644
--- a/src/mongo/db/repl/service_context_repl_mock.h
+++ b/src/mongo/db/repl/service_context_repl_mock.h
@@ -39,9 +39,7 @@ namespace repl {
*/
class ServiceContextReplMock : public ServiceContextNoop {
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client,
- unsigned opId,
- boost::optional<LogicalSessionId>) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
};
} // namespace repl
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index f090608337c..f4083be9901 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -43,10 +43,9 @@
#include "mongo/util/system_tick_source.h"
namespace mongo {
-
namespace {
-ServiceContext* globalServiceContext = NULL;
+ServiceContext* globalServiceContext = nullptr;
} // namespace
@@ -227,9 +226,8 @@ void ServiceContext::ClientDeleter::operator()(Client* client) const {
delete client;
}
-ServiceContext::UniqueOperationContext ServiceContext::makeOperationContext(
- Client* client, boost::optional<LogicalSessionId> lsid) {
- auto opCtx = _newOpCtx(client, _nextOpId.fetchAndAdd(1), std::move(lsid));
+ServiceContext::UniqueOperationContext ServiceContext::makeOperationContext(Client* client) {
+ auto opCtx = _newOpCtx(client, _nextOpId.fetchAndAdd(1));
auto observer = _clientObservers.begin();
try {
for (; observer != _clientObservers.cend(); ++observer) {
diff --git a/src/mongo/db/service_context.h b/src/mongo/db/service_context.h
index 02bc4b6a648..3cf830c3fe7 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -28,18 +28,16 @@
#pragma once
-#include <boost/optional.hpp>
-#include <memory>
#include <vector>
#include "mongo/base/disallow_copying.h"
#include "mongo/db/logical_session_cache.h"
-#include "mongo/db/logical_session_id.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/platform/unordered_set.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/functional.h"
+#include "mongo/stdx/memory.h"
#include "mongo/stdx/mutex.h"
#include "mongo/transport/session.h"
#include "mongo/util/clock_source.h"
@@ -227,10 +225,8 @@ public:
*
* "client" must not have an active operation context.
*
- * If provided, the LogicalSessionId links this operation to a logical session.
*/
- UniqueOperationContext makeOperationContext(
- Client* client, boost::optional<LogicalSessionId> lsid = boost::none);
+ UniqueOperationContext makeOperationContext(Client* client);
//
// Storage
@@ -453,9 +449,7 @@ private:
/**
* Returns a new OperationContext. Private, for use by makeOperationContext.
*/
- virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client,
- unsigned opId,
- boost::optional<LogicalSessionId>) = 0;
+ virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) = 0;
/**
* Kills the given operation.
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
index f3e40ee053b..c84f60aad55 100644
--- a/src/mongo/db/service_context_d.cpp
+++ b/src/mongo/db/service_context_d.cpp
@@ -269,10 +269,9 @@ const StorageEngine::Factory* StorageFactoriesIteratorMongoD::next() {
return _curr++->second;
}
-std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(
- Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid) {
+std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(Client* client, unsigned opId) {
invariant(&cc() == client);
- auto opCtx = stdx::make_unique<OperationContext>(client, opId, std::move(lsid));
+ auto opCtx = stdx::make_unique<OperationContext>(client, opId);
if (isMMAPV1()) {
opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
diff --git a/src/mongo/db/service_context_d.h b/src/mongo/db/service_context_d.h
index 33cae7595d4..0e96996206a 100644
--- a/src/mongo/db/service_context_d.h
+++ b/src/mongo/db/service_context_d.h
@@ -31,7 +31,6 @@
#include <boost/optional.hpp>
#include <vector>
-#include "mongo/db/logical_session_id.h"
#include "mongo/db/service_context.h"
#include "mongo/platform/unordered_set.h"
@@ -68,9 +67,7 @@ public:
OpObserver* getOpObserver() override;
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client,
- unsigned opId,
- boost::optional<LogicalSessionId> lsid) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
std::unique_ptr<StorageEngineLockFile> _lockFile;
diff --git a/src/mongo/db/service_context_noop.cpp b/src/mongo/db/service_context_noop.cpp
index 993d7fccfeb..64e1388b80e 100644
--- a/src/mongo/db/service_context_noop.cpp
+++ b/src/mongo/db/service_context_noop.cpp
@@ -35,8 +35,9 @@
#include "mongo/stdx/memory.h"
namespace mongo {
+
StorageEngine* ServiceContextNoop::getGlobalStorageEngine() {
- return NULL;
+ return nullptr;
}
void ServiceContextNoop::initializeGlobalStorageEngine() {}
@@ -66,9 +67,8 @@ StorageFactoriesIterator* ServiceContextNoop::makeStorageFactoriesIterator() {
return new EmptySFI();
}
-std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(
- Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid) {
- return stdx::make_unique<OperationContextNoop>(client, opId, std::move(lsid));
+std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(Client* client, unsigned opId) {
+ return stdx::make_unique<OperationContextNoop>(client, opId);
}
void ServiceContextNoop::setOpObserver(std::unique_ptr<OpObserver> opObserver) {}
@@ -76,4 +76,5 @@ void ServiceContextNoop::setOpObserver(std::unique_ptr<OpObserver> opObserver) {
OpObserver* ServiceContextNoop::getOpObserver() {
return nullptr;
}
+
} // namespace mongo
diff --git a/src/mongo/db/service_context_noop.h b/src/mongo/db/service_context_noop.h
index 81bd2222dbf..d6e2d12e525 100644
--- a/src/mongo/db/service_context_noop.h
+++ b/src/mongo/db/service_context_noop.h
@@ -28,13 +28,8 @@
#pragma once
-#include <boost/optional.hpp>
-
-#include "mongo/db/logical_session_id.h"
#include "mongo/db/service_context.h"
-#include "mongo/platform/atomic_word.h"
-
namespace mongo {
class ServiceContextNoop : public ServiceContext {
@@ -57,9 +52,7 @@ public:
OpObserver* getOpObserver() override;
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client,
- unsigned opId,
- boost::optional<LogicalSessionId> lsid) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
};
} // namespace mongo
diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp
index 504c1b497d0..0287f94d7d6 100644
--- a/src/mongo/db/service_entry_point_mongod.cpp
+++ b/src/mongo/db/service_entry_point_mongod.cpp
@@ -47,6 +47,7 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_session_id.h"
#include "mongo/db/logical_time_validator.h"
#include "mongo/db/ops/write_ops_exec.h"
#include "mongo/db/ops/write_ops_parsers.h"
@@ -525,6 +526,8 @@ void execCommandDatabase(OperationContext* opCtx,
rpc::readRequestMetadata(opCtx, request.body);
rpc::TrackingMetadata::get(opCtx).initWithOperName(command->getName());
+ initializeOperationSessionInfo(opCtx, request.body);
+
std::string dbname = request.getDatabase().toString();
uassert(
ErrorCodes::InvalidNamespace,
diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp
index 79cd0f44a0b..ae1ec79cd4b 100644
--- a/src/mongo/s/commands/strategy.cpp
+++ b/src/mongo/s/commands/strategy.cpp
@@ -267,6 +267,8 @@ void runAgainstRegistered(OperationContext* opCtx,
}
void runCommand(OperationContext* opCtx, const OpMsgRequest& request, BSONObjBuilder&& builder) {
+ initializeOperationSessionInfo(opCtx, request.body);
+
// Handle command option maxTimeMS.
uassert(ErrorCodes::InvalidOptions,
"no such command option $maxTimeMs; use maxTimeMS instead",