summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheahuychou Mao <cheahuychou.mao@mongodb.com>2020-03-25 13:59:23 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-27 16:38:39 +0000
commitbb67941a1ba9c04a58bc4cb74cfd02ec9f315024 (patch)
tree8f5a984cfc7a49a03af12519b93785d11845b424
parentefbe46ec29d5a7ba6bd1786a5c9b47fd44b731d3 (diff)
downloadmongo-bb67941a1ba9c04a58bc4cb74cfd02ec9f315024.tar.gz
SERVER-47141 Make failpoint in NetworkInterfaceTL sort targets before constructing CommandState
-rw-r--r--jstests/sharding/hedged_reads.js17
-rw-r--r--src/mongo/executor/network_interface_tl.cpp40
2 files changed, 27 insertions, 30 deletions
diff --git a/jstests/sharding/hedged_reads.js b/jstests/sharding/hedged_reads.js
index 9cf05016615..288f0d4d60a 100644
--- a/jstests/sharding/hedged_reads.js
+++ b/jstests/sharding/hedged_reads.js
@@ -94,15 +94,15 @@ st.rs0.nodes.forEach(function(conn) {
assert.commandWorked(
st.s.adminCommand({setParameter: 1, logComponentVerbosity: {network: {verbosity: 2}}}));
-jsTest.log("Verify the initial request is canceled when the hedged request responds first");
+jsTest.log("Verify that the initial request is canceled when the hedged request responds first");
try {
// Make the initial request block.
- setCommandDelay(sortedNodes[0], "find", kLargeTimeoutMS);
+ setCommandDelay(sortedNodes[0], "count", kLargeTimeoutMS);
const comment = "test_kill_initial_request_" + ObjectId();
assert.commandWorked(testDB.runCommand({
- find: collName,
- filter: {x: {$gte: 0}},
+ count: collName,
+ query: {x: {$gte: 0}},
$readPreference: {mode: "nearest"},
comment: comment
}));
@@ -117,18 +117,19 @@ try {
clearCommandDelay(sortedNodes[0]);
}
-jsTest.log("Verify the additional request is canceled when the initial request responds first");
+jsTest.log(
+ "Verify that the additional request is canceled when the initial request responds first");
try {
// Make the additional/hedged request block, set a large maxTimeMSForHedgedReads to prevent
// the remote host from killing the operation by itself.
assert.commandWorked(
st.s.adminCommand({setParameter: 1, maxTimeMSForHedgedReads: kLargeTimeoutMS}));
- setCommandDelay(sortedNodes[1], "find", kLargeTimeoutMS);
+ setCommandDelay(sortedNodes[1], "count", kLargeTimeoutMS);
const comment = "test_kill_additional_request_" + ObjectId();
assert.commandWorked(testDB.runCommand({
- find: collName,
- filter: {x: {$gte: 0}},
+ count: collName,
+ query: {x: {$gte: 0}},
$readPreference: {mode: "nearest"},
comment: comment
}));
diff --git a/src/mongo/executor/network_interface_tl.cpp b/src/mongo/executor/network_interface_tl.cpp
index fcae4dee869..3f2f6871c3d 100644
--- a/src/mongo/executor/network_interface_tl.cpp
+++ b/src/mongo/executor/network_interface_tl.cpp
@@ -419,6 +419,18 @@ Status NetworkInterfaceTL::startCommand(const TaskExecutor::CallbackHandle& cbHa
request.metadata = newMetadata.obj();
}
+ bool targetHostsInAlphabeticalOrder =
+ MONGO_unlikely(networkInterfaceSendRequestsToTargetHostsInAlphabeticalOrder.shouldFail());
+
+ if (targetHostsInAlphabeticalOrder) {
+ // Sort the target hosts by host names.
+ std::sort(request.target.begin(),
+ request.target.end(),
+ [](const HostAndPort& target1, const HostAndPort& target2) {
+ return target1.toString() < target2.toString();
+ });
+ }
+
auto [cmdState, future] = CommandState::make(this, request, cbHandle);
if (cmdState->requestOnAny.timeout != cmdState->requestOnAny.kNoTimeout) {
cmdState->deadline = cmdState->stopwatch.start() + cmdState->requestOnAny.timeout;
@@ -487,37 +499,21 @@ Status NetworkInterfaceTL::startCommand(const TaskExecutor::CallbackHandle& cbHa
RequestManager* rm = cmdState->requestManager.get();
- if (MONGO_unlikely(networkInterfaceSendRequestsToTargetHostsInAlphabeticalOrder.shouldFail())) {
- // Sort the target hosts by host names.
- std::sort(request.target.begin(),
- request.target.end(),
- [](const HostAndPort& target1, const HostAndPort& target2) {
- return target1.toString() < target2.toString();
- });
- }
-
// Attempt to get a connection to every target host
for (size_t idx = 0; idx < request.target.size() && !rm->usedAllConn(); ++idx) {
auto connFuture = _pool->get(request.target[idx], request.sslMode, request.timeout);
- if (connFuture.isReady()) {
+ // If connection future is ready or requests should be sent in order, send the request
+ // immediately.
+ if (connFuture.isReady() || targetHostsInAlphabeticalOrder) {
rm->trySend(std::move(connFuture).getNoThrow(), idx);
continue;
}
- if (MONGO_unlikely(
- networkInterfaceSendRequestsToTargetHostsInAlphabeticalOrder.shouldFail())) {
- // Wait for a connection so the requests are sent to target hosts in alphabetical order
- // of host names.
- auto swConn = std::move(connFuture).get();
+ // Otherwise, schedule the request.
+ std::move(connFuture).thenRunOn(_reactor).getAsync([requestStates, rm, idx](auto swConn) {
rm->trySend(std::move(swConn), idx);
- } else {
- // For every connection future we didn't have immediately ready, schedule
- std::move(connFuture)
- .thenRunOn(_reactor)
- .getAsync(
- [requestStates, rm, idx](auto swConn) { rm->trySend(std::move(swConn), idx); });
- }
+ });
}
return Status::OK();