diff options
author | Anton Korshunov <anton.korshunov@mongodb.com> | 2019-02-07 11:34:26 +0000 |
---|---|---|
committer | Anton Korshunov <anton.korshunov@mongodb.com> | 2019-02-11 15:55:15 +0000 |
commit | b54d9905a167867a2655910799573378aff2ce89 (patch) | |
tree | e11c129d50e07c288d08a04963068164d7174c05 /src/mongo | |
parent | 80f9a13324fc36b2deb400e5a185968f6fa8f64a (diff) | |
download | mongo-b54d9905a167867a2655910799573378aff2ce89.tar.gz |
SERVER-37456 Make the global CursorManager a decoration on ServiceContext
Diffstat (limited to 'src/mongo')
25 files changed, 100 insertions, 55 deletions
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index fef5105a9a5..15f9d4f1b22 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -280,7 +280,7 @@ public: const ServiceContext::UniqueOperationContext opCtx = cc().makeOperationContext(); auto now = opCtx->getServiceContext()->getPreciseClockSource()->now(); cursorStatsTimedOut.increment( - CursorManager::getGlobalCursorManager()->timeoutCursors(opCtx.get(), now)); + CursorManager::get(opCtx.get())->timeoutCursors(opCtx.get(), now)); } MONGO_IDLE_THREAD_BLOCK; sleepsecs(getClientCursorMonitorFrequencySecs()); diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp index a73aef6375a..0fde452ab39 100644 --- a/src/mongo/db/commands/find_cmd.cpp +++ b/src/mongo/db/commands/find_cmd.cpp @@ -399,16 +399,15 @@ public: if (shouldSaveCursor(opCtx, collection, state, exec.get())) { // Create a ClientCursor containing this plan executor and register it with the // cursor manager. - ClientCursorPin pinnedCursor = - CursorManager::getGlobalCursorManager()->registerCursor( - opCtx, - {std::move(exec), - nss, - AuthorizationSession::get(opCtx->getClient())->getAuthenticatedUserNames(), - repl::ReadConcernArgs::get(opCtx), - _request.body, - ClientCursorParams::LockPolicy::kLockExternally, - {Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find)}}); + ClientCursorPin pinnedCursor = CursorManager::get(opCtx)->registerCursor( + opCtx, + {std::move(exec), + nss, + AuthorizationSession::get(opCtx->getClient())->getAuthenticatedUserNames(), + repl::ReadConcernArgs::get(opCtx), + _request.body, + ClientCursorParams::LockPolicy::kLockExternally, + {Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find)}}); cursorId = pinnedCursor.getCursor()->cursorid(); invariant(!exec); diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp index 76bd4507d8e..350383d706f 100644 --- a/src/mongo/db/commands/getmore_cmd.cpp +++ b/src/mongo/db/commands/getmore_cmd.cpp @@ -304,7 +304,7 @@ public: boost::optional<AutoGetCollectionForRead> readLock; boost::optional<AutoStatsTracker> statsTracker; - auto cursorManager = CursorManager::getGlobalCursorManager(); + auto cursorManager = CursorManager::get(opCtx); auto cursorPin = uassertStatusOK(cursorManager->pinCursor(opCtx, _request.cursorid)); if (cursorPin->lockPolicy() == ClientCursorParams::LockPolicy::kLocksInternally) { diff --git a/src/mongo/db/commands/killcursors_cmd.cpp b/src/mongo/db/commands/killcursors_cmd.cpp index 6efecd22edc..dd820011c0f 100644 --- a/src/mongo/db/commands/killcursors_cmd.cpp +++ b/src/mongo/db/commands/killcursors_cmd.cpp @@ -67,7 +67,7 @@ public: private: Status _checkAuth(Client* client, const NamespaceString& nss, CursorId id) const final { auto opCtx = client->getOperationContext(); - return CursorManager::getGlobalCursorManager()->checkAuthForKillCursors(opCtx, id); + return CursorManager::get(opCtx)->checkAuthForKillCursors(opCtx, id); } Status _killCursor(OperationContext* opCtx, @@ -83,7 +83,7 @@ private: dbProfilingLevel); } - auto cursorManager = CursorManager::getGlobalCursorManager(); + auto cursorManager = CursorManager::get(opCtx); return cursorManager->killCursor(opCtx, id, true /* shouldAudit */); } } killCursorsCmd; diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index df886abf938..905ad7217ba 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -380,7 +380,7 @@ public: exec->detachFromOperationContext(); } // Drop db lock. Global cursor registration must be done without holding any locks. - auto pinnedCursor = CursorManager::getGlobalCursorManager()->registerCursor( + auto pinnedCursor = CursorManager::get(opCtx)->registerCursor( opCtx, {std::move(exec), cursorNss, diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 8c4b15606dc..65b63a14570 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -220,7 +220,7 @@ public: } // Drop collection lock. Global cursor registration must be done without holding any // locks. - const auto pinnedCursor = CursorManager::getGlobalCursorManager()->registerCursor( + const auto pinnedCursor = CursorManager::get(opCtx)->registerCursor( opCtx, {std::move(exec), nss, diff --git a/src/mongo/db/commands/repair_cursor.cpp b/src/mongo/db/commands/repair_cursor.cpp index 04c4d29fc49..6c6c764d328 100644 --- a/src/mongo/db/commands/repair_cursor.cpp +++ b/src/mongo/db/commands/repair_cursor.cpp @@ -101,7 +101,7 @@ public: exec->saveState(); exec->detachFromOperationContext(); - auto pinnedCursor = CursorManager::getGlobalCursorManager()->registerCursor( + auto pinnedCursor = CursorManager::get(opCtx)->registerCursor( opCtx, {std::move(exec), ns, diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index a8cefeb2caf..07cd48fbc80 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -645,8 +645,7 @@ Status runAggregate(OperationContext* opCtx, cursorParams.setAwaitData(true); } - auto pin = - CursorManager::getGlobalCursorManager()->registerCursor(opCtx, std::move(cursorParams)); + auto pin = CursorManager::get(opCtx)->registerCursor(opCtx, std::move(cursorParams)); cursors.emplace_back(pin.getCursor()); pins.emplace_back(std::move(pin)); } diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp index 3479b122b47..37beb7e8f19 100644 --- a/src/mongo/db/cursor_manager.cpp +++ b/src/mongo/db/cursor_manager.cpp @@ -62,16 +62,30 @@ namespace mongo { constexpr int CursorManager::kNumPartitions; -std::unique_ptr<CursorManager> globalCursorManager; +namespace { -MONGO_INITIALIZER(GlobalCursorManager) -(InitializerContext* context) { - globalCursorManager = std::make_unique<CursorManager>(); - return Status::OK(); +const auto serviceCursorManager = + ServiceContext::declareDecoration<std::unique_ptr<CursorManager>>(); + +ServiceContext::ConstructorActionRegisterer cursorManagerRegisterer{ + "CursorManagerRegisterer", [](ServiceContext* svcCtx) { + auto cursorManager = stdx::make_unique<CursorManager>(); + CursorManager::set(svcCtx, std::move(cursorManager)); + }}; +} // namespace + +CursorManager* CursorManager::get(ServiceContext* svcCtx) { + return serviceCursorManager(svcCtx).get(); +} + +CursorManager* CursorManager::get(OperationContext* optCtx) { + return get(optCtx->getServiceContext()); } -CursorManager* CursorManager::getGlobalCursorManager() { - return globalCursorManager.get(); +void CursorManager::set(ServiceContext* svcCtx, std::unique_ptr<CursorManager> newCursorManager) { + invariant(newCursorManager); + auto& cursorManager = serviceCursorManager(svcCtx); + cursorManager = std::move(newCursorManager); } std::pair<Status, int> CursorManager::killCursorsWithMatchingSessions( diff --git a/src/mongo/db/cursor_manager.h b/src/mongo/db/cursor_manager.h index f05beb73dc4..0def0d520d1 100644 --- a/src/mongo/db/cursor_manager.h +++ b/src/mongo/db/cursor_manager.h @@ -69,9 +69,20 @@ class PlanExecutor; class CursorManager { public: /** - * Returns a pointer to the process-global cursor manager. + * Returns a pointer to the cursor manager defined within the specified ServiceContext. */ - static CursorManager* getGlobalCursorManager(); + static CursorManager* get(ServiceContext* svcCtx); + + /** + * Returns a pointer to the cursor manager defined within the specified OperationContext. + */ + static CursorManager* get(OperationContext* opCtx); + + /** + * Registers the new cursor manager within the specified ServiceContext. + */ + static void set(ServiceContext* svcCtx, std::unique_ptr<CursorManager> newCursorManager); + CursorManager(); diff --git a/src/mongo/db/kill_sessions_local.cpp b/src/mongo/db/kill_sessions_local.cpp index d244143ed4e..da0cd84a1e3 100644 --- a/src/mongo/db/kill_sessions_local.cpp +++ b/src/mongo/db/kill_sessions_local.cpp @@ -105,8 +105,7 @@ SessionKiller::Result killSessionsLocal(OperationContext* opCtx, killSessionsAbortUnpreparedTransactions(opCtx, matcher); uassertStatusOK(killSessionsLocalKillOps(opCtx, matcher)); - auto res = - CursorManager::getGlobalCursorManager()->killCursorsWithMatchingSessions(opCtx, matcher); + auto res = CursorManager::get(opCtx)->killCursorsWithMatchingSessions(opCtx, matcher); uassertStatusOK(res.first); return {std::vector<HostAndPort>{}}; diff --git a/src/mongo/db/logical_session_cache_impl.cpp b/src/mongo/db/logical_session_cache_impl.cpp index f7afce2fc3a..cb7270d10c5 100644 --- a/src/mongo/db/logical_session_cache_impl.cpp +++ b/src/mongo/db/logical_session_cache_impl.cpp @@ -385,7 +385,7 @@ void LogicalSessionCacheImpl::_refresh(Client* client) { KillAllSessionsByPatternSet patterns; - auto openCursorSessions = _service->getOpenCursorSessions(); + auto openCursorSessions = _service->getOpenCursorSessions(opCtx); // Exclude sessions added to _activeSessions from the openCursorSession to avoid race between // killing cursors on the removed sessions and creating sessions. { diff --git a/src/mongo/db/pipeline/process_interface_standalone.cpp b/src/mongo/db/pipeline/process_interface_standalone.cpp index 1cd3d461ab4..56150b9535e 100644 --- a/src/mongo/db/pipeline/process_interface_standalone.cpp +++ b/src/mongo/db/pipeline/process_interface_standalone.cpp @@ -383,7 +383,7 @@ std::vector<FieldPath> MongoInterfaceStandalone::collectDocumentKeyFieldsActingA std::vector<GenericCursor> MongoInterfaceStandalone::getIdleCursors( const intrusive_ptr<ExpressionContext>& expCtx, CurrentOpUserMode userMode) const { - return CursorManager::getGlobalCursorManager()->getIdleCursors(expCtx->opCtx, userMode); + return CursorManager::get(expCtx->opCtx)->getIdleCursors(expCtx->opCtx, userMode); } boost::optional<Document> MongoInterfaceStandalone::lookupSingleDocument( diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp index 7469cbd6746..6671d0afed2 100644 --- a/src/mongo/db/query/find.cpp +++ b/src/mongo/db/query/find.cpp @@ -279,7 +279,7 @@ Message getMore(OperationContext* opCtx, // These are set in the QueryResult msg we return. int resultFlags = ResultFlag_AwaitCapable; - auto cursorManager = CursorManager::getGlobalCursorManager(); + auto cursorManager = CursorManager::get(opCtx); auto statusWithCursorPin = cursorManager->pinCursor(opCtx, cursorid); if (statusWithCursorPin == ErrorCodes::CursorNotFound) { return makeCursorNotFoundResponse(); @@ -717,7 +717,7 @@ std::string runQuery(OperationContext* opCtx, const auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx); // Allocate a new ClientCursor and register it with the cursor manager. - ClientCursorPin pinnedCursor = CursorManager::getGlobalCursorManager()->registerCursor( + ClientCursorPin pinnedCursor = CursorManager::get(opCtx)->registerCursor( opCtx, {std::move(exec), nss, diff --git a/src/mongo/db/run_op_kill_cursors.cpp b/src/mongo/db/run_op_kill_cursors.cpp index bbade52a554..cb7dbf6f3e0 100644 --- a/src/mongo/db/run_op_kill_cursors.cpp +++ b/src/mongo/db/run_op_kill_cursors.cpp @@ -44,7 +44,7 @@ namespace mongo { namespace { bool killCursorIfAuthorized(OperationContext* opCtx, CursorId id) { - auto cursorManager = CursorManager::getGlobalCursorManager(); + auto cursorManager = CursorManager::get(opCtx); auto pin = cursorManager->pinCursor(opCtx, id, CursorManager::kNoCheckSession); if (!pin.isOK()) { diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index e9519e89b80..2142a5b7faa 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -1108,7 +1108,7 @@ DbResponse receivedGetMore(OperationContext* opCtx, // // If killing the cursor fails, ignore the error and don't try again. The cursor should // be reaped by the client cursor timeout thread. - CursorManager::getGlobalCursorManager() + CursorManager::get(opCtx) ->killCursor(opCtx, cursorid, false /* shouldAudit */) .ignore(); } diff --git a/src/mongo/db/service_liaison.h b/src/mongo/db/service_liaison.h index 854e0b5d240..db9db61ddd9 100644 --- a/src/mongo/db/service_liaison.h +++ b/src/mongo/db/service_liaison.h @@ -60,7 +60,7 @@ public: /** * Return a list of sessions that are currently attached to open cursors */ - virtual LogicalSessionIdSet getOpenCursorSessions() const = 0; + virtual LogicalSessionIdSet getOpenCursorSessions(OperationContext* opCtx) const = 0; /** * Schedule a job to be run at regular intervals until the server shuts down. diff --git a/src/mongo/db/service_liaison_mock.cpp b/src/mongo/db/service_liaison_mock.cpp index 8193943090e..bcc88d987ec 100644 --- a/src/mongo/db/service_liaison_mock.cpp +++ b/src/mongo/db/service_liaison_mock.cpp @@ -49,7 +49,7 @@ LogicalSessionIdSet MockServiceLiaisonImpl::getActiveOpSessions() const { return _activeSessions; } -LogicalSessionIdSet MockServiceLiaisonImpl::getOpenCursorSessions() const { +LogicalSessionIdSet MockServiceLiaisonImpl::getOpenCursorSessions(OperationContext* opCtx) const { stdx::unique_lock<stdx::mutex> lk(_mutex); return _cursorSessions; } diff --git a/src/mongo/db/service_liaison_mock.h b/src/mongo/db/service_liaison_mock.h index 327b04fd371..480cd5359f8 100644 --- a/src/mongo/db/service_liaison_mock.h +++ b/src/mongo/db/service_liaison_mock.h @@ -61,7 +61,7 @@ public: // Forwarding methods from the MockServiceLiaison LogicalSessionIdSet getActiveOpSessions() const; - LogicalSessionIdSet getOpenCursorSessions() const; + LogicalSessionIdSet getOpenCursorSessions(OperationContext* opCtx) const; Date_t now() const; void scheduleJob(PeriodicRunner::PeriodicJob job); void join(); @@ -105,8 +105,8 @@ public: return _impl->getActiveOpSessions(); } - LogicalSessionIdSet getOpenCursorSessions() const override { - return _impl->getOpenCursorSessions(); + LogicalSessionIdSet getOpenCursorSessions(OperationContext* opCtx) const override { + return _impl->getOpenCursorSessions(opCtx); } Date_t now() const override { diff --git a/src/mongo/db/service_liaison_mongod.cpp b/src/mongo/db/service_liaison_mongod.cpp index 364ed83438c..91ec14ed274 100644 --- a/src/mongo/db/service_liaison_mongod.cpp +++ b/src/mongo/db/service_liaison_mongod.cpp @@ -66,9 +66,9 @@ LogicalSessionIdSet ServiceLiaisonMongod::getActiveOpSessions() const { return activeSessions; } -LogicalSessionIdSet ServiceLiaisonMongod::getOpenCursorSessions() const { +LogicalSessionIdSet ServiceLiaisonMongod::getOpenCursorSessions(OperationContext* opCtx) const { LogicalSessionIdSet cursorSessions; - CursorManager::getGlobalCursorManager()->appendActiveSessions(&cursorSessions); + CursorManager::get(opCtx)->appendActiveSessions(&cursorSessions); return cursorSessions; } @@ -98,7 +98,7 @@ ServiceContext* ServiceLiaisonMongod::_context() { std::pair<Status, int> ServiceLiaisonMongod::killCursorsWithMatchingSessions( OperationContext* opCtx, const SessionKiller::Matcher& matcher) { - return CursorManager::getGlobalCursorManager()->killCursorsWithMatchingSessions(opCtx, matcher); + return CursorManager::get(opCtx)->killCursorsWithMatchingSessions(opCtx, matcher); } } // namespace mongo diff --git a/src/mongo/db/service_liaison_mongod.h b/src/mongo/db/service_liaison_mongod.h index 5cd081f8823..c812be6a8fd 100644 --- a/src/mongo/db/service_liaison_mongod.h +++ b/src/mongo/db/service_liaison_mongod.h @@ -53,7 +53,7 @@ namespace mongo { class ServiceLiaisonMongod : public ServiceLiaison { public: LogicalSessionIdSet getActiveOpSessions() const override; - LogicalSessionIdSet getOpenCursorSessions() const override; + LogicalSessionIdSet getOpenCursorSessions(OperationContext* opCtx) const override; void scheduleJob(PeriodicRunner::PeriodicJob job) override; diff --git a/src/mongo/db/service_liaison_mongos.cpp b/src/mongo/db/service_liaison_mongos.cpp index c52ec45fb6b..a34d619e682 100644 --- a/src/mongo/db/service_liaison_mongos.cpp +++ b/src/mongo/db/service_liaison_mongos.cpp @@ -66,7 +66,7 @@ LogicalSessionIdSet ServiceLiaisonMongos::getActiveOpSessions() const { return activeSessions; } -LogicalSessionIdSet ServiceLiaisonMongos::getOpenCursorSessions() const { +LogicalSessionIdSet ServiceLiaisonMongos::getOpenCursorSessions(OperationContext* opCtx) const { LogicalSessionIdSet openCursorSessions; invariant(hasGlobalServiceContext()); diff --git a/src/mongo/db/service_liaison_mongos.h b/src/mongo/db/service_liaison_mongos.h index ecf08d5d822..23173f4f684 100644 --- a/src/mongo/db/service_liaison_mongos.h +++ b/src/mongo/db/service_liaison_mongos.h @@ -53,7 +53,7 @@ namespace mongo { class ServiceLiaisonMongos : public ServiceLiaison { public: LogicalSessionIdSet getActiveOpSessions() const override; - LogicalSessionIdSet getOpenCursorSessions() const override; + LogicalSessionIdSet getOpenCursorSessions(OperationContext* opCtx) const override; void scheduleJob(PeriodicRunner::PeriodicJob job) override; diff --git a/src/mongo/dbtests/cursor_manager_test.cpp b/src/mongo/dbtests/cursor_manager_test.cpp index 6de2ba0b3c4..9afefaa56f1 100644 --- a/src/mongo/dbtests/cursor_manager_test.cpp +++ b/src/mongo/dbtests/cursor_manager_test.cpp @@ -552,5 +552,29 @@ TEST_F(CursorManagerTestCustomOpCtx, MultipleCursorsMultipleSessions) { ASSERT(cursors2.find(cursor2) != cursors2.end()); } +/** + * Test that a CursorManager is registered with the global ServiceContext. + */ +TEST(CursorManagerTest, RegisteredWithGlobalServiceContext) { + CursorManager* cursorManager = CursorManager::get(getGlobalServiceContext()); + ASSERT(cursorManager); +} + +/** + * Test that a CursorManager is registered with a custom ServiceContext. + */ +TEST_F(CursorManagerTest, RegisteredWithCustomServiceContext) { + CursorManager* cursorManager = CursorManager::get(_queryServiceContext->getServiceContext()); + ASSERT(cursorManager); +} + +/** + * Test that a CursorManager is accessible via an OperationContext. + */ +TEST_F(CursorManagerTest, CanAccessFromOperationContext) { + CursorManager* cursorManager = CursorManager::get(_opCtx.get()); + ASSERT(cursorManager); +} + } // namespace } // namespace mongo diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 5b37ac26582..392326b2f3e 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -303,8 +303,8 @@ public: { // Check that a cursor has been registered with the global cursor manager, and has // already returned its first batch of results. - auto pinnedCursor = unittest::assertGet( - CursorManager::getGlobalCursorManager()->pinCursor(&_opCtx, cursorId)); + auto pinnedCursor = + unittest::assertGet(CursorManager::get(&_opCtx)->pinCursor(&_opCtx, cursorId)); ASSERT_EQUALS(std::uint64_t(2), pinnedCursor.getCursor()->nReturnedSoFar()); } @@ -367,7 +367,7 @@ public: _client.dropCollection("unittests.querytests.GetMoreInvalidRequest"); } void run() { - auto startNumCursors = CursorManager::getGlobalCursorManager()->numCursors(); + auto startNumCursors = CursorManager::get(&_opCtx)->numCursors(); // Create a collection with some data. const char* ns = "unittests.querytests.GetMoreInvalidRequest"; @@ -394,9 +394,8 @@ public: AssertionException); // Check that the cursor still exists. - ASSERT_EQ(startNumCursors + 1, CursorManager::getGlobalCursorManager()->numCursors()); - ASSERT_OK( - CursorManager::getGlobalCursorManager()->pinCursor(&_opCtx, cursorId).getStatus()); + ASSERT_EQ(startNumCursors + 1, CursorManager::get(&_opCtx)->numCursors()); + ASSERT_OK(CursorManager::get(&_opCtx)->pinCursor(&_opCtx, cursorId).getStatus()); // Check that the cursor can be iterated until all documents are returned. while (cursor->more()) { @@ -406,7 +405,7 @@ public: ASSERT_EQUALS(1000, count); // The cursor should no longer exist, since we exhausted it. - ASSERT_EQ(startNumCursors, CursorManager::getGlobalCursorManager()->numCursors()); + ASSERT_EQ(startNumCursors, CursorManager::get(&_opCtx)->numCursors()); } }; @@ -1280,7 +1279,7 @@ public: } size_t numCursorsOpen() { - return CursorManager::getGlobalCursorManager()->numCursors(); + return CursorManager::get(&_opCtx)->numCursors(); } const char* ns() { |