Skip to content

Commit c6c9416

Browse files
committed
SERVER-41493 Set request deadline based on maxtime ms in network interface
1 parent 5cbe016 commit c6c9416

File tree

2 files changed

+82
-8
lines changed

2 files changed

+82
-8
lines changed

src/mongo/executor/network_interface_integration_test.cpp

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,14 @@ class NetworkInterfaceTest : public NetworkInterfaceIntegrationFixture {
151151

152152
RemoteCommandRequest makeTestCommand(boost::optional<Milliseconds> timeout = boost::none,
153153
BSONObj cmd = BSON("echo" << 1 << "foo"
154-
<< "bar")) {
154+
<< "bar"),
155+
OperationContext* opCtx = nullptr) {
155156
auto cs = fixture();
156157
return RemoteCommandRequest(cs.getServers().front(),
157158
"admin",
158159
std::move(cmd),
159160
BSONObj(),
160-
nullptr,
161+
opCtx,
161162
timeout ? *timeout : RemoteCommandRequest::kNoTimeout);
162163
}
163164

@@ -289,6 +290,81 @@ TEST_F(NetworkInterfaceTest, AsyncOpTimeout) {
289290
}
290291
}
291292

293+
TEST_F(NetworkInterfaceTest, AsyncOpTimeoutWithOpCtxDeadlineSooner) {
294+
// Kick off operation
295+
auto cb = makeCallbackHandle();
296+
auto cmdObj = BSON("sleep" << 1 << "lock"
297+
<< "none"
298+
<< "secs" << 1000000000);
299+
300+
constexpr auto opCtxDeadline = Milliseconds{600};
301+
constexpr auto requestTimeout = Milliseconds{1000};
302+
303+
auto serviceContext = ServiceContext::make();
304+
auto client = serviceContext->makeClient("NetworkClient");
305+
auto opCtx = client->makeOperationContext();
306+
opCtx->setDeadlineAfterNowBy(opCtxDeadline, ErrorCodes::ExceededTimeLimit);
307+
308+
auto request = makeTestCommand(requestTimeout, cmdObj, opCtx.get());
309+
310+
auto deferred = runCommand(cb, request);
311+
312+
waitForIsMaster();
313+
314+
auto result = deferred.get();
315+
316+
// mongos doesn't implement the ping command, so ignore the response there, otherwise
317+
// check that we've timed out.
318+
if (pingCommandMissing(result)) {
319+
return;
320+
}
321+
322+
ASSERT_EQ(ErrorCodes::NetworkInterfaceExceededTimeLimit, result.status);
323+
ASSERT(result.elapsedMillis);
324+
// check that the request timeout uses the smaller of the operation context deadline and
325+
// the timeout specified in the request constructor.
326+
ASSERT_GTE(result.elapsedMillis.value(), opCtxDeadline);
327+
ASSERT_LT(result.elapsedMillis.value(), requestTimeout);
328+
assertNumOps(0u, 1u, 0u, 0u);
329+
}
330+
331+
TEST_F(NetworkInterfaceTest, AsyncOpTimeoutWithOpCtxDeadlineLater) {
332+
// Kick off operation
333+
auto cb = makeCallbackHandle();
334+
auto cmdObj = BSON("sleep" << 1 << "lock"
335+
<< "none"
336+
<< "secs" << 1000000000);
337+
338+
constexpr auto opCtxDeadline = Milliseconds{1000};
339+
constexpr auto requestTimeout = Milliseconds{600};
340+
341+
auto serviceContext = ServiceContext::make();
342+
auto client = serviceContext->makeClient("NetworkClient");
343+
auto opCtx = client->makeOperationContext();
344+
opCtx->setDeadlineAfterNowBy(opCtxDeadline, ErrorCodes::ExceededTimeLimit);
345+
auto request = makeTestCommand(requestTimeout, cmdObj, opCtx.get());
346+
347+
auto deferred = runCommand(cb, request);
348+
349+
waitForIsMaster();
350+
351+
auto result = deferred.get();
352+
353+
// mongos doesn't implement the ping command, so ignore the response there, otherwise
354+
// check that we've timed out.
355+
if (pingCommandMissing(result)) {
356+
return;
357+
}
358+
359+
ASSERT_EQ(ErrorCodes::NetworkInterfaceExceededTimeLimit, result.status);
360+
ASSERT(result.elapsedMillis);
361+
// check that the request timeout uses the smaller of the operation context deadline and
362+
// the timeout specified in the request constructor.
363+
ASSERT_GTE(result.elapsedMillis.value(), requestTimeout);
364+
ASSERT_LT(result.elapsedMillis.value(), opCtxDeadline);
365+
assertNumOps(0u, 1u, 0u, 0u);
366+
}
367+
292368
TEST_F(NetworkInterfaceTest, StartCommand) {
293369
auto commandRequest = BSON("echo" << 1 << "boop"
294370
<< "bop");

src/mongo/executor/remote_command_request.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,10 @@ RemoteCommandRequestBase::RemoteCommandRequestBase(RequestId requestId,
5959
const BSONObj& metadataObj,
6060
OperationContext* opCtx,
6161
Milliseconds timeoutMillis)
62-
: id(requestId),
63-
dbname(theDbName),
64-
metadata(metadataObj),
65-
cmdObj(theCmdObj),
66-
opCtx(opCtx),
67-
timeout(timeoutMillis) {}
62+
: id(requestId), dbname(theDbName), metadata(metadataObj), cmdObj(theCmdObj), opCtx(opCtx) {
63+
timeout = opCtx ? std::min<Milliseconds>(opCtx->getRemainingMaxTimeMillis(), timeoutMillis)
64+
: timeoutMillis;
65+
}
6866

6967
RemoteCommandRequestBase::RemoteCommandRequestBase() : id(requestIdCounter.addAndFetch(1)) {}
7068

0 commit comments

Comments
 (0)