diff options
author | Shaileja Jain <shaileja.jain@gmail.com> | 2019-07-29 17:18:05 -0400 |
---|---|---|
committer | Shaileja Jain <shaileja.jain@gmail.com> | 2019-08-01 11:52:56 -0400 |
commit | c6c9416779f3786b071bfbaff9a2baa13aad4d0e (patch) | |
tree | d70f5a626a7ba1cdb397aad234010675c33b348b /src/mongo/executor | |
parent | 5cbe01663884b321c45145c29bb9d9668125392e (diff) | |
download | mongo-c6c9416779f3786b071bfbaff9a2baa13aad4d0e.tar.gz |
SERVER-41493 Set request deadline based on maxtime ms in network interface
Diffstat (limited to 'src/mongo/executor')
-rw-r--r-- | src/mongo/executor/network_interface_integration_test.cpp | 80 | ||||
-rw-r--r-- | src/mongo/executor/remote_command_request.cpp | 10 |
2 files changed, 82 insertions, 8 deletions
diff --git a/src/mongo/executor/network_interface_integration_test.cpp b/src/mongo/executor/network_interface_integration_test.cpp index 2723f66bde7..f4f05bbc538 100644 --- a/src/mongo/executor/network_interface_integration_test.cpp +++ b/src/mongo/executor/network_interface_integration_test.cpp @@ -151,13 +151,14 @@ public: RemoteCommandRequest makeTestCommand(boost::optional<Milliseconds> timeout = boost::none, BSONObj cmd = BSON("echo" << 1 << "foo" - << "bar")) { + << "bar"), + OperationContext* opCtx = nullptr) { auto cs = fixture(); return RemoteCommandRequest(cs.getServers().front(), "admin", std::move(cmd), BSONObj(), - nullptr, + opCtx, timeout ? *timeout : RemoteCommandRequest::kNoTimeout); } @@ -289,6 +290,81 @@ TEST_F(NetworkInterfaceTest, AsyncOpTimeout) { } } +TEST_F(NetworkInterfaceTest, AsyncOpTimeoutWithOpCtxDeadlineSooner) { + // Kick off operation + auto cb = makeCallbackHandle(); + auto cmdObj = BSON("sleep" << 1 << "lock" + << "none" + << "secs" << 1000000000); + + constexpr auto opCtxDeadline = Milliseconds{600}; + constexpr auto requestTimeout = Milliseconds{1000}; + + auto serviceContext = ServiceContext::make(); + auto client = serviceContext->makeClient("NetworkClient"); + auto opCtx = client->makeOperationContext(); + opCtx->setDeadlineAfterNowBy(opCtxDeadline, ErrorCodes::ExceededTimeLimit); + + auto request = makeTestCommand(requestTimeout, cmdObj, opCtx.get()); + + auto deferred = runCommand(cb, request); + + waitForIsMaster(); + + auto result = deferred.get(); + + // mongos doesn't implement the ping command, so ignore the response there, otherwise + // check that we've timed out. + if (pingCommandMissing(result)) { + return; + } + + ASSERT_EQ(ErrorCodes::NetworkInterfaceExceededTimeLimit, result.status); + ASSERT(result.elapsedMillis); + // check that the request timeout uses the smaller of the operation context deadline and + // the timeout specified in the request constructor. + ASSERT_GTE(result.elapsedMillis.value(), opCtxDeadline); + ASSERT_LT(result.elapsedMillis.value(), requestTimeout); + assertNumOps(0u, 1u, 0u, 0u); +} + +TEST_F(NetworkInterfaceTest, AsyncOpTimeoutWithOpCtxDeadlineLater) { + // Kick off operation + auto cb = makeCallbackHandle(); + auto cmdObj = BSON("sleep" << 1 << "lock" + << "none" + << "secs" << 1000000000); + + constexpr auto opCtxDeadline = Milliseconds{1000}; + constexpr auto requestTimeout = Milliseconds{600}; + + auto serviceContext = ServiceContext::make(); + auto client = serviceContext->makeClient("NetworkClient"); + auto opCtx = client->makeOperationContext(); + opCtx->setDeadlineAfterNowBy(opCtxDeadline, ErrorCodes::ExceededTimeLimit); + auto request = makeTestCommand(requestTimeout, cmdObj, opCtx.get()); + + auto deferred = runCommand(cb, request); + + waitForIsMaster(); + + auto result = deferred.get(); + + // mongos doesn't implement the ping command, so ignore the response there, otherwise + // check that we've timed out. + if (pingCommandMissing(result)) { + return; + } + + ASSERT_EQ(ErrorCodes::NetworkInterfaceExceededTimeLimit, result.status); + ASSERT(result.elapsedMillis); + // check that the request timeout uses the smaller of the operation context deadline and + // the timeout specified in the request constructor. + ASSERT_GTE(result.elapsedMillis.value(), requestTimeout); + ASSERT_LT(result.elapsedMillis.value(), opCtxDeadline); + assertNumOps(0u, 1u, 0u, 0u); +} + TEST_F(NetworkInterfaceTest, StartCommand) { auto commandRequest = BSON("echo" << 1 << "boop" << "bop"); diff --git a/src/mongo/executor/remote_command_request.cpp b/src/mongo/executor/remote_command_request.cpp index be7ce253dd9..38b745bebee 100644 --- a/src/mongo/executor/remote_command_request.cpp +++ b/src/mongo/executor/remote_command_request.cpp @@ -59,12 +59,10 @@ RemoteCommandRequestBase::RemoteCommandRequestBase(RequestId requestId, const BSONObj& metadataObj, OperationContext* opCtx, Milliseconds timeoutMillis) - : id(requestId), - dbname(theDbName), - metadata(metadataObj), - cmdObj(theCmdObj), - opCtx(opCtx), - timeout(timeoutMillis) {} + : id(requestId), dbname(theDbName), metadata(metadataObj), cmdObj(theCmdObj), opCtx(opCtx) { + timeout = opCtx ? std::min<Milliseconds>(opCtx->getRemainingMaxTimeMillis(), timeoutMillis) + : timeoutMillis; +} RemoteCommandRequestBase::RemoteCommandRequestBase() : id(requestIdCounter.addAndFetch(1)) {} |