diff options
author | Ben Caimano <ben.caimano@10gen.com> | 2020-10-06 21:59:59 +0000 |
---|---|---|
committer | Ben Caimano <ben.caimano@10gen.com> | 2020-10-23 21:48:21 +0000 |
commit | 907bf93c57b1f689ecf690df6beb7cb07fd9fa5e (patch) | |
tree | 85cbf314c9033aa7bc59f8a8faa6a850be7cb0f0 | |
parent | 243a506fca5b2cca017192ff455e1520d9783a9e (diff) | |
download | mongo-907bf93c57b1f689ecf690df6beb7cb07fd9fa5e.tar.gz |
SERVER-49109 Move to the dedicated executor after blocking commands
-rw-r--r-- | src/mongo/db/commands.h | 28 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 17 | ||||
-rw-r--r-- | src/mongo/s/commands/strategy.cpp | 13 |
3 files changed, 58 insertions, 0 deletions
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 @@ -630,6 +630,34 @@ public: } /** + * 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 */ virtual bool supportsReadMirroring() const { 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<DbResponse> 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); |