diff options
-rw-r--r-- | src/mongo/db/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/client.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/client.h | 8 | ||||
-rw-r--r-- | src/mongo/db/exec/queued_data_stage_test.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/exec/sort_test.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/operation_context.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/operation_context.h | 12 | ||||
-rw-r--r-- | src/mongo/db/operation_context_impl.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/operation_context_impl.h | 4 | ||||
-rw-r--r-- | src/mongo/db/operation_context_noop.h | 10 | ||||
-rw-r--r-- | src/mongo/db/operation_context_test.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/repl/service_context_repl_mock.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/service_context_repl_mock.h | 4 | ||||
-rw-r--r-- | src/mongo/db/service_context.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/service_context.h | 11 | ||||
-rw-r--r-- | src/mongo/db/service_context_d.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/service_context_d.h | 6 | ||||
-rw-r--r-- | src/mongo/db/service_context_noop.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/service_context_noop.h | 7 |
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 |