From 8387824b3ac937b0489fcb94c590cc663b47348c Mon Sep 17 00:00:00 2001 From: Benety Goh Date: Fri, 1 Feb 2019 13:23:54 -0500 Subject: SERVER-37643 IndexBuildsCoordinatorMongod task inherits CurOp and OperationContext info from caller thread This supports copying an OperationContext's deadline and timeout error across thread boundaries. This also adds OperationContext::getTimeoutError(). --- src/mongo/db/SConscript | 1 + src/mongo/db/index_builds_coordinator_mongod.cpp | 24 +++++++++++++++++++++++- src/mongo/db/operation_context.cpp | 4 ++++ src/mongo/db/operation_context.h | 5 +++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index ad4e1b37163..af94c070fc2 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -932,6 +932,7 @@ env.Library( "$BUILD_DIR/mongo/util/concurrency/thread_pool", ], LIBDEPS_PRIVATE=[ + 'curop', "$BUILD_DIR/mongo/db/catalog/commit_quorum_options", '$BUILD_DIR/mongo/db/catalog/uuid_catalog', ], diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp index 6b3677ee604..c6668a80e91 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod.cpp @@ -34,6 +34,7 @@ #include "mongo/db/index_builds_coordinator_mongod.h" #include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/curop.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/util/assert_util.h" @@ -106,9 +107,30 @@ IndexBuildsCoordinatorMongod::startIndexBuild(OperationContext* opCtx, return status; } - status = _threadPool.schedule([ this, buildUUID ]() noexcept { + // Task in thread pool should retain the caller's deadline. + auto deadline = opCtx->getDeadline(); + auto timeoutError = opCtx->getTimeoutError(); + + // Task in thread pool should have similar CurOp representation to the caller so that it can be + // identified as a createIndexes operation. + BSONObj opDesc; + { + stdx::unique_lock lk(*opCtx->getClient()); + auto curOp = CurOp::get(opCtx); + opDesc = curOp->opDescription().getOwned(); + } + + status = _threadPool.schedule([ this, buildUUID, deadline, timeoutError, opDesc ]() noexcept { auto opCtx = Client::getCurrent()->makeOperationContext(); + opCtx->setDeadlineByDate(deadline, timeoutError); + + { + stdx::unique_lock lk(*opCtx->getClient()); + auto curOp = CurOp::get(opCtx.get()); + curOp->setOpDescription_inlock(opDesc); + } + // Sets up and runs the index build. Sets result and cleans up index build. _runIndexBuild(opCtx.get(), buildUUID); }); diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp index 87080f39195..11ca8b8f641 100644 --- a/src/mongo/db/operation_context.cpp +++ b/src/mongo/db/operation_context.cpp @@ -155,6 +155,10 @@ bool OperationContext::hasDeadlineExpired() const { return now >= getDeadline(); } +ErrorCodes::Error OperationContext::getTimeoutError() const { + return _timeoutError; +} + Milliseconds OperationContext::getRemainingMaxTimeMillis() const { if (!hasDeadline()) { return Milliseconds::max(); diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h index e1ea8e6d61d..389797c2e1c 100644 --- a/src/mongo/db/operation_context.h +++ b/src/mongo/db/operation_context.h @@ -311,6 +311,11 @@ public: return _deadline; } + /** + * Returns the error code used when this operation's time limit is reached. + */ + ErrorCodes::Error getTimeoutError() const; + /** * Returns the number of milliseconds remaining for this operation's time limit or * Milliseconds::max() if the operation has no time limit. -- cgit v1.2.1