summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/client.cpp5
-rw-r--r--src/mongo/db/client.h8
-rw-r--r--src/mongo/db/exec/queued_data_stage_test.cpp4
-rw-r--r--src/mongo/db/exec/sort_test.cpp4
-rw-r--r--src/mongo/db/operation_context.cpp5
-rw-r--r--src/mongo/db/operation_context.h12
-rw-r--r--src/mongo/db/operation_context_impl.cpp7
-rw-r--r--src/mongo/db/operation_context_impl.h4
-rw-r--r--src/mongo/db/operation_context_noop.h10
-rw-r--r--src/mongo/db/operation_context_test.cpp37
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.cpp6
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.h4
-rw-r--r--src/mongo/db/service_context.cpp5
-rw-r--r--src/mongo/db/service_context.h11
-rw-r--r--src/mongo/db/service_context_d.cpp6
-rw-r--r--src/mongo/db/service_context_d.h6
-rw-r--r--src/mongo/db/service_context_noop.cpp5
-rw-r--r--src/mongo/db/service_context_noop.h7
19 files changed, 121 insertions, 26 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 667ef37e8db..abced2c53ec 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -192,6 +192,7 @@ env.CppUnitTest(
'operation_context_test.cpp',
],
LIBDEPS=[
+ 'logical_session_id',
'service_context',
'$BUILD_DIR/mongo/db/auth/authorization_manager_mock_init',
'$BUILD_DIR/mongo/db/service_context_noop_init',
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 9fdb3ce6cf6..3f26dc039c0 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -124,8 +124,9 @@ void Client::reportState(BSONObjBuilder& builder) {
}
}
-ServiceContext::UniqueOperationContext Client::makeOperationContext() {
- return getServiceContext()->makeOperationContext(this);
+ServiceContext::UniqueOperationContext Client::makeOperationContext(
+ boost::optional<LogicalSessionId> lsid) {
+ return getServiceContext()->makeOperationContext(this, std::move(lsid));
}
void Client::setOperationContext(OperationContext* opCtx) {
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index e37dd6d7afa..64e2850785f 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -36,8 +36,11 @@
#pragma once
+#include <boost/optional.hpp>
+
#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"
@@ -151,8 +154,11 @@ public:
/**
* Makes a new operation context representing an operation on this client. At most
* one operation context may be in scope on a client at a time.
+ *
+ * If provided, the LogicalSessionId links this operation to a logical session.
*/
- ServiceContext::UniqueOperationContext makeOperationContext();
+ ServiceContext::UniqueOperationContext makeOperationContext(
+ boost::optional<LogicalSessionId> lsid = boost::none);
/**
* 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 398cb1a1281..08a2a57569d 100644
--- a/src/mongo/db/exec/queued_data_stage_test.cpp
+++ b/src/mongo/db/exec/queued_data_stage_test.cpp
@@ -32,6 +32,8 @@
#include "mongo/db/exec/queued_data_stage.h"
+#include <boost/optional.hpp>
+
#include "mongo/db/exec/working_set.h"
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/service_context.h"
@@ -53,7 +55,7 @@ public:
_service = stdx::make_unique<ServiceContextNoop>();
_service.get()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
_client = _service.get()->makeClient("test");
- _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0));
+ _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0, boost::none));
_opCtx = _opCtxNoop.get();
}
diff --git a/src/mongo/db/exec/sort_test.cpp b/src/mongo/db/exec/sort_test.cpp
index 5dfd2db70ab..8f200ffb0a3 100644
--- a/src/mongo/db/exec/sort_test.cpp
+++ b/src/mongo/db/exec/sort_test.cpp
@@ -32,6 +32,8 @@
#include "mongo/db/exec/sort.h"
+#include <boost/optional.hpp>
+
#include "mongo/db/exec/queued_data_stage.h"
#include "mongo/db/json.h"
#include "mongo/db/operation_context_noop.h"
@@ -53,7 +55,7 @@ public:
_service = stdx::make_unique<ServiceContextNoop>();
_service.get()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
_client = _service.get()->makeClient("test");
- _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0));
+ _opCtxNoop.reset(new OperationContextNoop(_client.get(), 0, boost::none));
_opCtx = _opCtxNoop.get();
CollatorFactoryInterface::set(_service.get(), stdx::make_unique<CollatorFactoryMock>());
}
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
index 4170797da1e..b185185876b 100644
--- a/src/mongo/db/operation_context.cpp
+++ b/src/mongo/db/operation_context.cpp
@@ -75,9 +75,12 @@ MONGO_FP_DECLARE(checkForInterruptFail);
} // namespace
-OperationContext::OperationContext(Client* client, unsigned int opId)
+OperationContext::OperationContext(Client* client,
+ unsigned int opId,
+ boost::optional<LogicalSessionId> lsid)
: _client(client),
_opId(opId),
+ _lsid(std::move(lsid)),
_elapsedTime(client ? client->getServiceContext()->getTickSource()
: SystemTickSource::get()) {}
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 54be41d5e29..b60bf3d863b 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -28,12 +28,14 @@
#pragma once
+#include <boost/optional.hpp>
#include <memory>
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
#include "mongo/db/client.h"
#include "mongo/db/concurrency/locker.h"
+#include "mongo/db/logical_session_id.h"
#include "mongo/db/storage/recovery_unit.h"
#include "mongo/db/storage/recovery_unit.h"
#include "mongo/db/storage/storage_options.h"
@@ -268,6 +270,13 @@ public:
}
/**
+ * Returns the session ID associated with this operation, if there is one.
+ */
+ boost::optional<LogicalSessionId> getLogicalSessionId() const {
+ return _lsid;
+ }
+
+ /**
* Returns WriteConcernOptions of the current operation
*/
const WriteConcernOptions& getWriteConcern() const {
@@ -379,7 +388,7 @@ public:
Microseconds getRemainingMaxTimeMicros() const;
protected:
- OperationContext(Client* client, unsigned int opId);
+ OperationContext(Client* client, unsigned int opId, boost::optional<LogicalSessionId> lsid);
private:
/**
@@ -411,6 +420,7 @@ private:
friend class repl::UnreplicatedWritesBlock;
Client* const _client;
const unsigned int _opId;
+ boost::optional<LogicalSessionId> _lsid;
std::unique_ptr<Locker> _locker;
diff --git a/src/mongo/db/operation_context_impl.cpp b/src/mongo/db/operation_context_impl.cpp
index 0ccdbbbfbef..2a878ce239d 100644
--- a/src/mongo/db/operation_context_impl.cpp
+++ b/src/mongo/db/operation_context_impl.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/operation_context_impl.h"
+#include <boost/optional.hpp>
#include <memory>
#include "mongo/db/client.h"
@@ -51,8 +52,10 @@ std::unique_ptr<Locker> newLocker() {
using std::string;
-OperationContextImpl::OperationContextImpl(Client* client, unsigned opId)
- : OperationContext(client, opId) {
+OperationContextImpl::OperationContextImpl(Client* client,
+ unsigned opId,
+ boost::optional<LogicalSessionId> lsid)
+ : OperationContext(client, opId, std::move(lsid)) {
setLockState(newLocker());
StorageEngine* storageEngine = getServiceContext()->getGlobalStorageEngine();
setRecoveryUnit(storageEngine->newRecoveryUnit(), kNotInUnitOfWork);
diff --git a/src/mongo/db/operation_context_impl.h b/src/mongo/db/operation_context_impl.h
index bc23dcbb089..2f33944535b 100644
--- a/src/mongo/db/operation_context_impl.h
+++ b/src/mongo/db/operation_context_impl.h
@@ -27,8 +27,10 @@
*/
#pragma once
+#include <boost/optional.hpp>
#include <string>
+#include "mongo/db/logical_session_id.h"
#include "mongo/db/operation_context.h"
namespace mongo {
@@ -43,7 +45,7 @@ public:
private:
friend class ServiceContextMongoD;
- OperationContextImpl(Client* client, unsigned opId);
+ OperationContextImpl(Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid);
};
} // namespace mongo
diff --git a/src/mongo/db/operation_context_noop.h b/src/mongo/db/operation_context_noop.h
index 695fabb14f5..7505561c76c 100644
--- a/src/mongo/db/operation_context_noop.h
+++ b/src/mongo/db/operation_context_noop.h
@@ -27,7 +27,10 @@
*/
#pragma once
+#include <boost/optional.hpp>
+
#include "mongo/db/concurrency/locker_noop.h"
+#include "mongo/db/logical_session_id.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/storage/recovery_unit_noop.h"
#include "mongo/stdx/memory.h"
@@ -43,8 +46,8 @@ 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) {}
- OperationContextNoop(RecoveryUnit* ru) : OperationContextNoop(nullptr, 0) {
+ OperationContextNoop() : OperationContextNoop(nullptr, 0, boost::none) {}
+ OperationContextNoop(RecoveryUnit* ru) : OperationContextNoop(nullptr, 0, boost::none) {
setRecoveryUnit(ru, kNotInUnitOfWork);
}
@@ -52,7 +55,8 @@ public:
/**
* This constructor is for use by ServiceContexts, and should not be called directly.
*/
- OperationContextNoop(Client* client, unsigned int opId) : OperationContext(client, opId) {
+ OperationContextNoop(Client* client, unsigned int opId, boost::optional<LogicalSessionId> lsid)
+ : OperationContext(client, opId, std::move(lsid)) {
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 95f53cf8053..33e23f45593 100644
--- a/src/mongo/db/operation_context_test.cpp
+++ b/src/mongo/db/operation_context_test.cpp
@@ -28,7 +28,10 @@
#include "mongo/platform/basic.h"
+#include <boost/optional.hpp>
+
#include "mongo/db/client.h"
+#include "mongo/db/logical_session_id.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
@@ -69,6 +72,40 @@ 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
+ auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto client = serviceCtx->makeClient("OperationContextTest");
+
+ // No session id
+ {
+ auto opCtx = client->makeOperationContext();
+ ASSERT(!opCtx->getLogicalSessionId());
+ }
+
+ {
+ auto opCtx = serviceCtx->makeOperationContext(client.get());
+ ASSERT(!opCtx->getLogicalSessionId());
+ }
+
+ // With a session id
+ auto res = LogicalSessionId::parse("00000000-abab-4000-8000-000000000000");
+ ASSERT(res.isOK());
+ auto lsid = res.getValue();
+
+ {
+ auto opCtx = client->makeOperationContext(lsid);
+ ASSERT(opCtx->getLogicalSessionId());
+ ASSERT_EQUALS(*(opCtx->getLogicalSessionId()), lsid);
+ }
+
+ {
+ auto opCtx = serviceCtx->makeOperationContext(client.get(), lsid);
+ ASSERT(opCtx->getLogicalSessionId());
+ ASSERT_EQUALS(*(opCtx->getLogicalSessionId()), lsid);
+ }
+}
+
class OperationDeadlineTests : public unittest::Test {
public:
void setUp() {
diff --git a/src/mongo/db/repl/service_context_repl_mock.cpp b/src/mongo/db/repl/service_context_repl_mock.cpp
index ba88cf149bd..f411a45bfc7 100644
--- a/src/mongo/db/repl/service_context_repl_mock.cpp
+++ b/src/mongo/db/repl/service_context_repl_mock.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/repl/service_context_repl_mock.h"
+#include <boost/optional.hpp>
#include <memory>
#include "mongo/db/concurrency/lock_state.h"
@@ -40,8 +41,9 @@
namespace mongo {
namespace repl {
-std::unique_ptr<OperationContext> ServiceContextReplMock::_newOpCtx(Client* client, unsigned opId) {
- auto opCtx = stdx::make_unique<OperationContextNoop>(client, opId);
+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));
opCtx->releaseLockState();
opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
return std::move(opCtx);
diff --git a/src/mongo/db/repl/service_context_repl_mock.h b/src/mongo/db/repl/service_context_repl_mock.h
index 8ffb92a9da1..dfc68a020d7 100644
--- a/src/mongo/db/repl/service_context_repl_mock.h
+++ b/src/mongo/db/repl/service_context_repl_mock.h
@@ -39,7 +39,9 @@ namespace repl {
*/
class ServiceContextReplMock : public ServiceContextNoop {
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client,
+ unsigned opId,
+ boost::optional<LogicalSessionId>) override;
};
} // namespace repl
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index de50199c149..32e14c36aac 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -211,8 +211,9 @@ void ServiceContext::ClientDeleter::operator()(Client* client) const {
delete client;
}
-ServiceContext::UniqueOperationContext ServiceContext::makeOperationContext(Client* client) {
- auto opCtx = _newOpCtx(client, _nextOpId.fetchAndAdd(1));
+ServiceContext::UniqueOperationContext ServiceContext::makeOperationContext(
+ Client* client, boost::optional<LogicalSessionId> lsid) {
+ auto opCtx = _newOpCtx(client, _nextOpId.fetchAndAdd(1), std::move(lsid));
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 ad5af47e360..566ed7fb650 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -28,10 +28,12 @@
#pragma once
+#include <boost/optional.hpp>
#include <memory>
#include <vector>
#include "mongo/base/disallow_copying.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"
@@ -222,8 +224,11 @@ public:
* Creates a new OperationContext on "client".
*
* "client" must not have an active operation context.
+ *
+ * If provided, the LogicalSessionId links this operation to a logical session.
*/
- UniqueOperationContext makeOperationContext(Client* client);
+ UniqueOperationContext makeOperationContext(
+ Client* client, boost::optional<LogicalSessionId> lsid = boost::none);
//
// Storage
@@ -401,7 +406,9 @@ private:
/**
* Returns a new OperationContext. Private, for use by makeOperationContext.
*/
- virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) = 0;
+ virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client,
+ unsigned opId,
+ boost::optional<LogicalSessionId>) = 0;
/**
* Kills the given operation.
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
index b04012a8e51..a5debda247f 100644
--- a/src/mongo/db/service_context_d.cpp
+++ b/src/mongo/db/service_context_d.cpp
@@ -265,9 +265,11 @@ const StorageEngine::Factory* StorageFactoriesIteratorMongoD::next() {
return _curr++->second;
}
-std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(Client* client, unsigned opId) {
+std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(
+ Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid) {
invariant(&cc() == client);
- return std::unique_ptr<OperationContextImpl>(new OperationContextImpl(client, opId));
+ return std::unique_ptr<OperationContextImpl>(
+ new OperationContextImpl(client, opId, std::move(lsid)));
}
void ServiceContextMongoD::setOpObserver(std::unique_ptr<OpObserver> opObserver) {
diff --git a/src/mongo/db/service_context_d.h b/src/mongo/db/service_context_d.h
index 6de44fe1503..33cae7595d4 100644
--- a/src/mongo/db/service_context_d.h
+++ b/src/mongo/db/service_context_d.h
@@ -28,8 +28,10 @@
#pragma once
+#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"
@@ -66,7 +68,9 @@ public:
OpObserver* getOpObserver() override;
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client,
+ unsigned opId,
+ boost::optional<LogicalSessionId> lsid) 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 4e9b67fc28f..42fd30f3f3c 100644
--- a/src/mongo/db/service_context_noop.cpp
+++ b/src/mongo/db/service_context_noop.cpp
@@ -67,8 +67,9 @@ StorageFactoriesIterator* ServiceContextNoop::makeStorageFactoriesIterator() {
return new EmptySFI();
}
-std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(Client* client, unsigned opId) {
- return stdx::make_unique<OperationContextNoop>(client, opId);
+std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(
+ Client* client, unsigned opId, boost::optional<LogicalSessionId> lsid) {
+ return stdx::make_unique<OperationContextNoop>(client, opId, std::move(lsid));
}
void ServiceContextNoop::setOpObserver(std::unique_ptr<OpObserver> opObserver) {}
diff --git a/src/mongo/db/service_context_noop.h b/src/mongo/db/service_context_noop.h
index 4fe7ef6e022..81bd2222dbf 100644
--- a/src/mongo/db/service_context_noop.h
+++ b/src/mongo/db/service_context_noop.h
@@ -28,6 +28,9 @@
#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"
@@ -54,7 +57,9 @@ public:
OpObserver* getOpObserver() override;
private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
+ std::unique_ptr<OperationContext> _newOpCtx(Client* client,
+ unsigned opId,
+ boost::optional<LogicalSessionId> lsid) override;
};
} // namespace mongo