summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Morilha <daniel.morilha@mongodb.com>2022-05-27 19:02:58 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-27 20:16:46 +0000
commita474d4efa5a999526e696423af5d30f4f5187613 (patch)
tree0cf942c5c123999881377e9596440a416075a39e /src
parent015bbbacf80e79c5661f5efef5cb255c02eacc1f (diff)
downloadmongo-a474d4efa5a999526e696423af5d30f4f5187613.tar.gz
SERVER-66260 Modify executor::RemoteCommandRequest to accept an Options argument
Transitioning from `RemoteCommandRequestBase::HedgeOptions` into a generic Options `struct`ure in order to accommodate new options into requests for remote commands. ``` struct RemoteCommandRequestBase { struct Options { size_t hedgeCount = 0; int maxTimeMSForHedgedReads = 0; bool isHedgeEnabled = false; bool fireAndForget = false; }; ``` The `boost::optional` which wrapped the previous structure was deprecated in favor of a new `isHedgeEnabled` boolean field which should be logically equivalent. `fireAndForget` was also moved from the outer class inside. Code and tests were appropriately adjusted.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/client/async_client.cpp4
-rw-r--r--src/mongo/db/mirror_maestro.cpp8
-rw-r--r--src/mongo/db/repl/tenant_migration_shard_merge_util.cpp2
-rw-r--r--src/mongo/executor/network_interface_integration_test.cpp55
-rw-r--r--src/mongo/executor/network_interface_tl.cpp12
-rw-r--r--src/mongo/executor/network_interface_tl.h6
-rw-r--r--src/mongo/executor/network_test_env.cpp5
-rw-r--r--src/mongo/executor/remote_command_request.cpp37
-rw-r--r--src/mongo/executor/remote_command_request.h41
-rw-r--r--src/mongo/s/async_requests_sender.cpp11
-rw-r--r--src/mongo/s/hedge_options_util.cpp19
-rw-r--r--src/mongo/s/hedge_options_util.h13
-rw-r--r--src/mongo/s/hedge_options_util_test.cpp9
-rw-r--r--src/mongo/s/query/establish_cursors.cpp5
14 files changed, 99 insertions, 128 deletions
diff --git a/src/mongo/client/async_client.cpp b/src/mongo/client/async_client.cpp
index 030e22de674..3a568fa7e31 100644
--- a/src/mongo/client/async_client.cpp
+++ b/src/mongo/client/async_client.cpp
@@ -320,9 +320,7 @@ Future<executor::RemoteCommandResponse> AsyncDBClient::runCommandRequest(
auto opMsgRequest = OpMsgRequest::fromDBAndBody(
std::move(request.dbname), std::move(request.cmdObj), std::move(request.metadata));
opMsgRequest.securityToken = request.securityToken;
- auto fireAndForget =
- request.fireAndForgetMode == executor::RemoteCommandRequest::FireAndForgetMode::kOn;
- return runCommand(std::move(opMsgRequest), baton, fireAndForget)
+ return runCommand(std::move(opMsgRequest), baton, request.options.fireAndForget)
.then([this, startTimer = std::move(startTimer)](rpc::UniqueReply response) {
return executor::RemoteCommandResponse(*response, startTimer.elapsed());
});
diff --git a/src/mongo/db/mirror_maestro.cpp b/src/mongo/db/mirror_maestro.cpp
index 303a7cc0af9..c2d0fe9e67b 100644
--- a/src/mongo/db/mirror_maestro.cpp
+++ b/src/mongo/db/mirror_maestro.cpp
@@ -418,10 +418,10 @@ void MirrorMaestroImpl::_mirror(const std::vector<HostAndPort>& hosts,
auto newRequest = executor::RemoteCommandRequest(
host, invocation->ns().db().toString(), payload, nullptr);
- if (MONGO_likely(!mirrorMaestroExpectsResponse.shouldFail())) {
- // If we're not expecting a response, set to fire and forget
- newRequest.fireAndForgetMode = executor::RemoteCommandRequest::FireAndForgetMode::kOn;
- }
+
+ newRequest.options.fireAndForget = true;
+ if (MONGO_unlikely(mirrorMaestroExpectsResponse.shouldFail()))
+ newRequest.options.fireAndForget = false;
LOGV2_DEBUG(31455, 4, "About to mirror", "host"_attr = host, "request"_attr = newRequest);
diff --git a/src/mongo/db/repl/tenant_migration_shard_merge_util.cpp b/src/mongo/db/repl/tenant_migration_shard_merge_util.cpp
index 84a4e493738..3d5deee7ce2 100644
--- a/src/mongo/db/repl/tenant_migration_shard_merge_util.cpp
+++ b/src/mongo/db/repl/tenant_migration_shard_merge_util.cpp
@@ -311,7 +311,7 @@ SemiFuture<void> keepBackupCursorAlive(CancellationSource cancellationSource,
namespaceString.db().toString(),
std::move(BSON("getMore" << cursorId << "collection" << namespaceString.coll().toString())),
nullptr);
- getMoreRequest.fireAndForgetMode = executor::RemoteCommandRequest::FireAndForgetMode::kOn;
+ getMoreRequest.options.fireAndForget = true;
return AsyncTry([executor, getMoreRequest, cancellationSource] {
return executor->scheduleRemoteCommand(std::move(getMoreRequest),
diff --git a/src/mongo/executor/network_interface_integration_test.cpp b/src/mongo/executor/network_interface_integration_test.cpp
index 4b750e8002e..8ea77a73888 100644
--- a/src/mongo/executor/network_interface_integration_test.cpp
+++ b/src/mongo/executor/network_interface_integration_test.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include <algorithm>
#include <exception>
#include <memory>
@@ -172,13 +170,10 @@ public:
ASSERT_EQ(getInProgress(), 0);
}
- RemoteCommandRequest makeTestCommand(
- Milliseconds timeout,
- BSONObj cmd,
- OperationContext* opCtx = nullptr,
- boost::optional<RemoteCommandRequest::HedgeOptions> hedgeOptions = boost::none,
- RemoteCommandRequest::FireAndForgetMode fireAndForgetMode =
- RemoteCommandRequest::FireAndForgetMode::kOff) {
+ RemoteCommandRequest makeTestCommand(Milliseconds timeout,
+ BSONObj cmd,
+ OperationContext* opCtx = nullptr,
+ RemoteCommandRequest::Options options = {}) {
auto cs = fixture();
return RemoteCommandRequest(cs.getServers().front(),
"admin",
@@ -186,8 +181,7 @@ public:
BSONObj(),
opCtx,
timeout,
- hedgeOptions,
- fireAndForgetMode);
+ std::move(options));
}
BSONObj makeEchoCmdObj() {
@@ -373,13 +367,12 @@ TEST_F(NetworkInterfaceTest, CancelRemotely) {
auto cbh = makeCallbackHandle();
auto deferred = [&] {
+ RemoteCommandRequest::Options options;
+ options.isHedgeEnabled = true;
// Kick off an "echo" operation, which should block until cancelCommand causes
// the operation to be killed.
- auto deferred = runCommand(cbh,
- makeTestCommand(kNoTimeout,
- makeEchoCmdObj(),
- nullptr /* opCtx */,
- RemoteCommandRequest::HedgeOptions()));
+ auto deferred = runCommand(
+ cbh, makeTestCommand(kNoTimeout, makeEchoCmdObj(), nullptr /* opCtx */, options));
// Wait for the "echo" operation to start.
numCurrentOpRan += waitForCommandToStart("echo", kMaxWait);
@@ -431,12 +424,11 @@ TEST_F(NetworkInterfaceTest, CancelRemotelyTimedOut) {
auto cbh = makeCallbackHandle();
auto deferred = [&] {
+ RemoteCommandRequest::Options options;
+ options.isHedgeEnabled = true;
// Kick off a blocking "echo" operation.
- auto deferred = runCommand(cbh,
- makeTestCommand(kNoTimeout,
- makeEchoCmdObj(),
- nullptr /* opCtx */,
- RemoteCommandRequest::HedgeOptions()));
+ auto deferred = runCommand(
+ cbh, makeTestCommand(kNoTimeout, makeEchoCmdObj(), nullptr /* opCtx */, options));
// Wait for the "echo" operation to start.
numCurrentOpRan += waitForCommandToStart("echo", kMaxWait);
@@ -597,8 +589,9 @@ TEST_F(NetworkInterfaceTest, AsyncOpTimeoutWithOpCtxDeadlineLater) {
}
TEST_F(NetworkInterfaceTest, StartCommand) {
- auto request = makeTestCommand(
- kNoTimeout, makeEchoCmdObj(), nullptr /* opCtx */, RemoteCommandRequest::HedgeOptions());
+ RemoteCommandRequest::Options options;
+ options.isHedgeEnabled = true;
+ auto request = makeTestCommand(kNoTimeout, makeEchoCmdObj(), nullptr /* opCtx */, options);
auto deferred = runCommand(makeCallbackHandle(), std::move(request));
@@ -640,13 +633,12 @@ TEST_F(NetworkInterfaceTest, FireAndForget) {
const int numFireAndForgetRequests = 3;
std::vector<Future<RemoteCommandResponse>> futures;
+ RemoteCommandRequest::Options options;
+ options.fireAndForget = true;
for (int i = 0; i < numFireAndForgetRequests; i++) {
auto cbh = makeCallbackHandle();
- auto fireAndForgetRequest = makeTestCommand(kNoTimeout,
- makeEchoCmdObj(),
- nullptr /* opCtx */,
- boost::none /* hedgeOptions */,
- RemoteCommandRequest::FireAndForgetMode::kOn);
+ auto fireAndForgetRequest =
+ makeTestCommand(kNoTimeout, makeEchoCmdObj(), nullptr /* opCtx */, options);
futures.push_back(runCommand(cbh, fireAndForgetRequest));
}
@@ -677,8 +669,9 @@ TEST_F(NetworkInterfaceInternalClientTest, StartCommandOnAny) {
auto commandRequest = makeEchoCmdObj();
auto request = [&] {
auto cs = fixture();
- RemoteCommandRequestBase::HedgeOptions ho;
- ho.count = 1;
+ RemoteCommandRequestBase::Options options;
+ options.isHedgeEnabled = true;
+ options.hedgeCount = 1;
return RemoteCommandRequestOnAny({cs.getServers()},
"admin",
@@ -686,7 +679,7 @@ TEST_F(NetworkInterfaceInternalClientTest, StartCommandOnAny) {
BSONObj(),
nullptr,
RemoteCommandRequest::kNoTimeout,
- ho);
+ options);
}();
auto deferred = runCommandOnAny(makeCallbackHandle(), std::move(request));
diff --git a/src/mongo/executor/network_interface_tl.cpp b/src/mongo/executor/network_interface_tl.cpp
index ec4da0b474b..9ee2ffac0b6 100644
--- a/src/mongo/executor/network_interface_tl.cpp
+++ b/src/mongo/executor/network_interface_tl.cpp
@@ -378,7 +378,7 @@ NetworkInterfaceTL::CommandState::CommandState(NetworkInterfaceTL* interface_,
RemoteCommandRequestOnAny request_,
const TaskExecutor::CallbackHandle& cbHandle_)
: CommandStateBase(interface_, std::move(request_), cbHandle_),
- hedgeCount(requestOnAny.hedgeOptions ? requestOnAny.hedgeOptions->count + 1 : 1) {}
+ hedgeCount(requestOnAny.options.isHedgeEnabled ? requestOnAny.options.hedgeCount + 1 : 1) {}
auto NetworkInterfaceTL::CommandState::make(NetworkInterfaceTL* interface,
RemoteCommandRequestOnAny request,
@@ -560,7 +560,7 @@ Status NetworkInterfaceTL::startCommand(const TaskExecutor::CallbackHandle& cbHa
bool targetHostsInAlphabeticalOrder =
MONGO_unlikely(networkInterfaceSendRequestsToTargetHostsInAlphabeticalOrder.shouldFail(
- [request](const BSONObj&) { return request.hedgeOptions != boost::none; }));
+ [request](const BSONObj&) { return request.options.isHedgeEnabled; }));
if (targetHostsInAlphabeticalOrder) {
// Sort the target hosts by host names.
@@ -571,7 +571,7 @@ Status NetworkInterfaceTL::startCommand(const TaskExecutor::CallbackHandle& cbHa
});
}
- if ((request.target.size() > 1) && !request.hedgeOptions &&
+ if ((request.target.size() > 1) && !request.options.isHedgeEnabled &&
!gOpportunisticSecondaryTargeting.load()) {
request.target.resize(1);
}
@@ -582,7 +582,7 @@ Status NetworkInterfaceTL::startCommand(const TaskExecutor::CallbackHandle& cbHa
}
cmdState->baton = baton;
- if (_svcCtx && cmdState->requestOnAny.hedgeOptions) {
+ if (_svcCtx && cmdState->requestOnAny.options.isHedgeEnabled) {
auto hm = HedgingMetrics::get(_svcCtx);
invariant(hm);
hm->incrementNumTotalOperations();
@@ -836,10 +836,10 @@ void NetworkInterfaceTL::RequestManager::trySend(
auto request = &requestState->request.get();
if (requestState->isHedge) {
- invariant(request->hedgeOptions);
+ invariant(request->options.isHedgeEnabled);
invariant(WireSpec::instance().get()->isInternalClient);
- auto hedgingMaxTimeMS = Milliseconds(request->hedgeOptions->maxTimeMSForHedgedReads);
+ auto hedgingMaxTimeMS = Milliseconds(request->options.maxTimeMSForHedgedReads);
if (request->timeout == RemoteCommandRequest::kNoTimeout ||
hedgingMaxTimeMS < request->timeout) {
LOGV2_DEBUG(4647200,
diff --git a/src/mongo/executor/network_interface_tl.h b/src/mongo/executor/network_interface_tl.h
index 8564413806a..fefb300f6fe 100644
--- a/src/mongo/executor/network_interface_tl.h
+++ b/src/mongo/executor/network_interface_tl.h
@@ -148,11 +148,11 @@ private:
* Return the maximum amount of requests that can come from this command.
*/
size_t maxConcurrentRequests() const noexcept {
- if (!requestOnAny.hedgeOptions) {
- return 1ull;
+ if (!requestOnAny.options.isHedgeEnabled) {
+ return 1;
}
- return requestOnAny.hedgeOptions->count + 1ull;
+ return requestOnAny.options.hedgeCount + 1;
}
/**
diff --git a/src/mongo/executor/network_test_env.cpp b/src/mongo/executor/network_test_env.cpp
index 9a128705054..ea59f563117 100644
--- a/src/mongo/executor/network_test_env.cpp
+++ b/src/mongo/executor/network_test_env.cpp
@@ -56,8 +56,7 @@ void NetworkTestEnv::onCommands(std::vector<OnCommandFunction> funcs) {
auto resultStatus = func(request);
- if (request.fireAndForgetMode ==
- executor::RemoteCommandRequestBase::FireAndForgetMode::kOn) {
+ if (request.options.fireAndForget) {
_mockNetwork->blackHole(noi);
} else if (resultStatus.isOK()) {
BSONObjBuilder result(std::move(resultStatus.getValue()));
@@ -82,7 +81,7 @@ void NetworkTestEnv::onCommandWithMetadata(OnCommandWithMetadataFunction func) {
auto cmdResponseStatus = func(request);
- if (request.fireAndForgetMode == executor::RemoteCommandRequestBase::FireAndForgetMode::kOn) {
+ if (request.options.fireAndForget) {
_mockNetwork->blackHole(noi);
} else if (cmdResponseStatus.isOK()) {
BSONObjBuilder result(std::move(cmdResponseStatus.data));
diff --git a/src/mongo/executor/remote_command_request.cpp b/src/mongo/executor/remote_command_request.cpp
index 1a62a4b30c4..0d1a4750889 100644
--- a/src/mongo/executor/remote_command_request.cpp
+++ b/src/mongo/executor/remote_command_request.cpp
@@ -60,14 +60,12 @@ RemoteCommandRequestBase::RemoteCommandRequestBase(RequestId requestId,
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis,
- boost::optional<HedgeOptions> hedgeOptions,
- FireAndForgetMode fireAndForgetMode)
+ Options options)
: id(requestId),
dbname(theDbName),
metadata(metadataObj),
opCtx(opCtx),
- hedgeOptions(hedgeOptions),
- fireAndForgetMode(fireAndForgetMode),
+ options(options),
timeout(timeoutMillis) {
// If there is a comment associated with the current operation, append it to the command that we
// are about to dispatch to the shards.
@@ -82,7 +80,7 @@ RemoteCommandRequestBase::RemoteCommandRequestBase(RequestId requestId,
<< query_request_helper::kMaxTimeMSOpOnlyField,
!cmdObj.hasField(query_request_helper::kMaxTimeMSOpOnlyField));
- if (hedgeOptions) {
+ if (options.isHedgeEnabled) {
operationKey.emplace(UUID::gen());
cmdObj = cmdObj.addField(BSON("clientOperationKey" << operationKey.get()).firstElement());
}
@@ -130,16 +128,9 @@ RemoteCommandRequestImpl<T>::RemoteCommandRequestImpl(RequestId requestId,
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis,
- boost::optional<HedgeOptions> hedgeOptions,
- FireAndForgetMode fireAndForgetMode)
- : RemoteCommandRequestBase(requestId,
- theDbName,
- theCmdObj,
- metadataObj,
- opCtx,
- timeoutMillis,
- hedgeOptions,
- fireAndForgetMode),
+ Options options)
+ : RemoteCommandRequestBase(
+ requestId, theDbName, theCmdObj, metadataObj, opCtx, timeoutMillis, options),
target(theTarget) {
if constexpr (std::is_same_v<T, std::vector<HostAndPort>>) {
invariant(!theTarget.empty());
@@ -153,8 +144,7 @@ RemoteCommandRequestImpl<T>::RemoteCommandRequestImpl(const T& theTarget,
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis,
- boost::optional<HedgeOptions> hedgeOptions,
- FireAndForgetMode fireAndForgetMode)
+ Options options)
: RemoteCommandRequestImpl(requestIdCounter.addAndFetch(1),
theTarget,
theDbName,
@@ -162,8 +152,7 @@ RemoteCommandRequestImpl<T>::RemoteCommandRequestImpl(const T& theTarget,
metadataObj,
opCtx,
timeoutMillis,
- hedgeOptions,
- fireAndForgetMode) {}
+ options) {}
template <typename T>
std::string RemoteCommandRequestImpl<T>::toString() const {
@@ -180,9 +169,9 @@ std::string RemoteCommandRequestImpl<T>::toString() const {
out << " expDate:" << (*dateScheduled + timeout).toString();
}
- if (hedgeOptions) {
+ if (options.isHedgeEnabled) {
invariant(operationKey);
- out << " hedgeOptions.count: " << hedgeOptions->count;
+ out << " options.hedgeCount: " << options.hedgeCount;
out << " operationKey: " << operationKey.get();
}
@@ -209,5 +198,11 @@ bool RemoteCommandRequestImpl<T>::operator!=(const RemoteCommandRequestImpl& rhs
template struct RemoteCommandRequestImpl<HostAndPort>;
template struct RemoteCommandRequestImpl<std::vector<HostAndPort>>;
+void RemoteCommandRequestBase::Options::resetHedgeOptions() {
+ hedgeCount = 0;
+ maxTimeMSForHedgedReads = 0;
+ isHedgeEnabled = false;
+}
+
} // namespace executor
} // namespace mongo
diff --git a/src/mongo/executor/remote_command_request.h b/src/mongo/executor/remote_command_request.h
index 83209ffec04..7d232a34756 100644
--- a/src/mongo/executor/remote_command_request.h
+++ b/src/mongo/executor/remote_command_request.h
@@ -44,13 +44,14 @@ namespace mongo {
namespace executor {
struct RemoteCommandRequestBase {
- struct HedgeOptions {
- size_t count = 0;
+ struct Options {
+ void resetHedgeOptions();
+ size_t hedgeCount = 0;
int maxTimeMSForHedgedReads = 0;
+ bool isHedgeEnabled = false;
+ bool fireAndForget = false;
};
- enum FireAndForgetMode { kOn, kOff };
-
// Indicates that there is no timeout for the request to complete
static constexpr Milliseconds kNoTimeout{-1};
@@ -64,8 +65,7 @@ struct RemoteCommandRequestBase {
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis,
- boost::optional<HedgeOptions> hedgeOptions,
- FireAndForgetMode fireAndForgetMode);
+ Options options);
// Internal id of this request. Not interpreted and used for tracing purposes only.
RequestId id;
@@ -84,12 +84,10 @@ struct RemoteCommandRequestBase {
// metadata attachment (i.e., replication).
OperationContext* opCtx{nullptr};
- boost::optional<HedgeOptions> hedgeOptions;
+ Options options;
boost::optional<UUID> operationKey;
- FireAndForgetMode fireAndForgetMode = FireAndForgetMode::kOff;
-
// When false, the network interface will refrain from enforcing the 'timeout' for this request,
// but will still pass the timeout on as maxTimeMSOpOnly.
bool enforceLocalTimeout = true;
@@ -142,8 +140,7 @@ struct RemoteCommandRequestImpl : RemoteCommandRequestBase {
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis = kNoTimeout,
- boost::optional<HedgeOptions> hedgeOptions = boost::none,
- FireAndForgetMode fireAndForgetMode = FireAndForgetMode::kOff);
+ Options options = {});
RemoteCommandRequestImpl(const Target& theTarget,
const std::string& theDbName,
@@ -151,24 +148,16 @@ struct RemoteCommandRequestImpl : RemoteCommandRequestBase {
const BSONObj& metadataObj,
OperationContext* opCtx,
Milliseconds timeoutMillis = kNoTimeout,
- boost::optional<HedgeOptions> hedgeOptions = boost::none,
- FireAndForgetMode fireAndForgetMode = FireAndForgetMode::kOff);
+ Options options = {});
RemoteCommandRequestImpl(const Target& theTarget,
const std::string& theDbName,
const BSONObj& theCmdObj,
const BSONObj& metadataObj,
OperationContext* opCtx,
- boost::optional<HedgeOptions> hedgeOptions,
- FireAndForgetMode fireAndForgetMode = FireAndForgetMode::kOff)
- : RemoteCommandRequestImpl(theTarget,
- theDbName,
- theCmdObj,
- metadataObj,
- opCtx,
- kNoTimeout,
- hedgeOptions,
- fireAndForgetMode) {}
+ Options options)
+ : RemoteCommandRequestImpl(
+ theTarget, theDbName, theCmdObj, metadataObj, opCtx, kNoTimeout, options) {}
RemoteCommandRequestImpl(const Target& theTarget,
@@ -176,16 +165,14 @@ struct RemoteCommandRequestImpl : RemoteCommandRequestBase {
const BSONObj& theCmdObj,
OperationContext* opCtx,
Milliseconds timeoutMillis = kNoTimeout,
- boost::optional<HedgeOptions> hedgeOptions = boost::none,
- FireAndForgetMode fireAndForgetMode = FireAndForgetMode::kOff)
+ Options options = {})
: RemoteCommandRequestImpl(theTarget,
theDbName,
theCmdObj,
rpc::makeEmptyMetadata(),
opCtx,
timeoutMillis,
- hedgeOptions,
- fireAndForgetMode) {}
+ options) {}
std::string toString() const;
diff --git a/src/mongo/s/async_requests_sender.cpp b/src/mongo/s/async_requests_sender.cpp
index 5c746049b3a..497e4c7fcbe 100644
--- a/src/mongo/s/async_requests_sender.cpp
+++ b/src/mongo/s/async_requests_sender.cpp
@@ -232,13 +232,10 @@ auto AsyncRequestsSender::RemoteData::scheduleRemoteCommand(std::vector<HostAndP
HostAndPort(data.getStringField("hostAndPort"))));
});
- auto hedgeOptions = extractHedgeOptions(_cmdObj, _ars->_readPreference);
- executor::RemoteCommandRequestOnAny request(std::move(hostAndPorts),
- _ars->_db,
- _cmdObj,
- _ars->_metadataObj,
- _ars->_opCtx,
- hedgeOptions);
+ executor::RemoteCommandRequestOnAny::Options options;
+ extractHedgeOptions(_cmdObj, _ars->_readPreference, options);
+ executor::RemoteCommandRequestOnAny request(
+ std::move(hostAndPorts), _ars->_db, _cmdObj, _ars->_metadataObj, _ars->_opCtx, options);
// We have to make a promise future pair because the TaskExecutor doesn't currently support a
// future returning variant of scheduleRemoteCommand
diff --git a/src/mongo/s/hedge_options_util.cpp b/src/mongo/s/hedge_options_util.cpp
index ce6e8ecc4b2..ebdfc3ddd86 100644
--- a/src/mongo/s/hedge_options_util.cpp
+++ b/src/mongo/s/hedge_options_util.cpp
@@ -32,7 +32,6 @@
#include "mongo/s/mongos_server_parameters_gen.h"
namespace mongo {
-
namespace {
// Only hedge commands that cannot trigger writes.
const std::set<std::string> supportedCmds{"collStats",
@@ -47,20 +46,20 @@ const std::set<std::string> supportedCmds{"collStats",
"planCacheListFilters"};
} // namespace
-boost::optional<executor::RemoteCommandRequestOnAny::HedgeOptions> extractHedgeOptions(
- const BSONObj& cmdObj, const ReadPreferenceSetting& readPref) {
+void extractHedgeOptions(const BSONObj& cmdObj,
+ const ReadPreferenceSetting& readPref,
+ executor::RemoteCommandRequestOnAny::Options& options) {
+ options.resetHedgeOptions();
if (!(gReadHedgingMode.load() == ReadHedgingMode::kOn && readPref.hedgingMode &&
readPref.hedgingMode->getEnabled())) {
- return boost::none;
+ return;
}
-
auto cmdName(cmdObj.firstElement().fieldNameStringData().toString());
-
if (supportedCmds.count(cmdName)) {
- return executor::RemoteCommandRequestOnAny::HedgeOptions{1,
- gMaxTimeMSForHedgedReads.load()};
+ options.hedgeCount = 1;
+ options.maxTimeMSForHedgedReads = gMaxTimeMSForHedgedReads.load();
+ options.isHedgeEnabled = true;
+ return;
}
- return boost::none;
}
-
} // namespace mongo
diff --git a/src/mongo/s/hedge_options_util.h b/src/mongo/s/hedge_options_util.h
index edce7b9ba16..58a14151410 100644
--- a/src/mongo/s/hedge_options_util.h
+++ b/src/mongo/s/hedge_options_util.h
@@ -36,10 +36,13 @@
namespace mongo {
/**
- * Constructs and returns hedge options based on the given cmd object and read preference
- * setting. If no hedging should be performed, returns boost::none.
+ * Configure the hedge-related data members of `options`. If the command
+ * specified by `cmdObj` and `readPref` is eligible for hedging, and hedging
+ * is globally enabled for this server, then the hedge-related parameters of
+ * `options` are set. Otherwise they are reset to their default values, which
+ * specify unhedged behavior.
*/
-boost::optional<executor::RemoteCommandRequestOnAny::HedgeOptions> extractHedgeOptions(
- const BSONObj& cmdObj, const ReadPreferenceSetting& readPref);
-
+void extractHedgeOptions(const BSONObj& cmdObj,
+ const ReadPreferenceSetting& readPref,
+ executor::RemoteCommandRequestOnAny::Options& options);
} // namespace mongo
diff --git a/src/mongo/s/hedge_options_util_test.cpp b/src/mongo/s/hedge_options_util_test.cpp
index 33808dfb9aa..b7736b4ad16 100644
--- a/src/mongo/s/hedge_options_util_test.cpp
+++ b/src/mongo/s/hedge_options_util_test.cpp
@@ -72,13 +72,12 @@ protected:
setParameters(serverParameters);
auto readPref = uassertStatusOK(ReadPreferenceSetting::fromInnerBSON(rspObj));
- auto hedgeOptions = extractHedgeOptions(cmdObj, readPref);
+ executor::RemoteCommandRequest::Options options;
+ extractHedgeOptions(cmdObj, readPref, options);
+ ASSERT_EQ(hedge, options.isHedgeEnabled);
if (hedge) {
- ASSERT_TRUE(hedgeOptions.has_value());
- ASSERT_EQ(hedgeOptions->maxTimeMSForHedgedReads, maxTimeMSForHedgedReads);
- } else {
- ASSERT_FALSE(hedgeOptions.has_value());
+ ASSERT_EQ(options.maxTimeMSForHedgedReads, maxTimeMSForHedgedReads);
}
}
diff --git a/src/mongo/s/query/establish_cursors.cpp b/src/mongo/s/query/establish_cursors.cpp
index 5f64ebdfe2e..baeb1d64581 100644
--- a/src/mongo/s/query/establish_cursors.cpp
+++ b/src/mongo/s/query/establish_cursors.cpp
@@ -304,14 +304,15 @@ void CursorEstablisher::_killOpOnShards(ServiceContext* srvCtx,
auto opCtx = tc->makeOperationContext();
for (auto&& host : remotes) {
+ executor::RemoteCommandRequest::Options options;
+ options.fireAndForget = true;
executor::RemoteCommandRequest request(
host,
"admin",
BSON("_killOperations" << 1 << "operationKeys" << BSON_ARRAY(opKey)),
opCtx.get(),
executor::RemoteCommandRequestBase::kNoTimeout,
- boost::none,
- executor::RemoteCommandRequestBase::FireAndForgetMode::kOn);
+ options);
// We do not process the response to the killOperations request (we make a good-faith
// attempt at cleaning up the cursors, but ignore any returned errors).