From 907bf93c57b1f689ecf690df6beb7cb07fd9fa5e Mon Sep 17 00:00:00 2001 From: Ben Caimano Date: Tue, 6 Oct 2020 21:59:59 +0000 Subject: SERVER-49109 Move to the dedicated executor after blocking commands --- src/mongo/db/commands.h | 28 ++++++++++++++++++++++++++++ src/mongo/db/service_entry_point_common.cpp | 17 +++++++++++++++++ src/mongo/s/commands/strategy.cpp | 13 +++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index 790c6123f8e..60fb3036daf 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -629,6 +629,34 @@ public: {kDefaultReadConcernNotPermitted}}; } + /** + * Returns if this invocation is safe to run on a borrowed threading model. + * + * In practice, this is attempting to predict if the operation will do network or storage reads + * and writes. It will allow auth commands for the most part, since while they do involve + * network or storage operations, they are not targeting the storage engine or remote + * mongo-server nodes. + */ + virtual bool isSafeForBorrowedThreads() const { + if (definition()->maintenanceMode() || !definition()->maintenanceOk()) { + // If the command has maintenance implications, it has storage implications. + return false; + } + + if (supportsWriteConcern()) { + // If the command supports write concern, it has storage and network implications. + return false; + } + + if (auto result = supportsReadConcern(repl::ReadConcernLevel::kMajorityReadConcern); + result.readConcernSupport.isOK()) { + // If the command supports read concern, it has storage and newtork implications. + return false; + } + + return true; + } + /** * Return if this invocation can be mirrored to secondaries */ diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 2b20ed67bab..af22da58f4e 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -98,6 +98,7 @@ #include "mongo/rpc/op_msg.h" #include "mongo/rpc/reply_builder_interface.h" #include "mongo/transport/ismaster_metrics.h" +#include "mongo/transport/service_executor.h" #include "mongo/transport/session.h" #include "mongo/util/duration.h" #include "mongo/util/fail_point.h" @@ -2253,6 +2254,22 @@ Future ServiceEntryPointCommon::handleRequest( [execContext = hr->executionContext](DbResponse response) -> void { // Set the response upon successful execution execContext->setResponse(std::move(response)); + + auto opCtx = execContext->getOpCtx(); + + auto seCtx = transport::ServiceExecutorContext::get(opCtx->getClient()); + if (!seCtx) { + // We were run by a background worker. + return; + } + + if (auto invocation = CommandInvocation::get(opCtx); + invocation && !invocation->isSafeForBorrowedThreads()) { + // If the last command wasn't safe for a borrowed thread, then let's move + // off of it. + seCtx->setThreadingModel( + transport::ServiceExecutor::ThreadingModel::kDedicated); + } }); }) .then([hr] { return hr->completeOperation(); }) diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index f83b490d0ef..f3f27506da7 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -85,6 +85,7 @@ #include "mongo/s/stale_exception.h" #include "mongo/s/transaction_router.h" #include "mongo/transport/ismaster_metrics.h" +#include "mongo/transport/service_executor.h" #include "mongo/transport/session.h" #include "mongo/util/fail_point.h" #include "mongo/util/scopeguard.h" @@ -287,6 +288,18 @@ void execCommandClient(OperationContext* opCtx, auto body = result->getBodyBuilder(); appendRequiredFieldsToResponse(opCtx, &body); + + auto seCtx = transport::ServiceExecutorContext::get(opCtx->getClient()); + if (!seCtx) { + // We were run by a background worker. + return; + } + + if (!invocation->isSafeForBorrowedThreads()) { + // If the last command wasn't safe for a borrowed thread, then let's move + // off of it. + seCtx->setThreadingModel(transport::ServiceExecutor::ThreadingModel::kDedicated); + } } MONGO_FAIL_POINT_DEFINE(doNotRefreshShardsOnRetargettingError); -- cgit v1.2.1