diff options
author | Amirsaman Memaripour <amirsaman.memaripour@mongodb.com> | 2020-11-02 20:04:42 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-09 01:02:09 +0000 |
commit | 7925d3e9a759e983a49cf44b90d58f77fbf7fb95 (patch) | |
tree | 1f6b717fd9756ea4fe17aca74d445cd12e91d46f /src/mongo/executor | |
parent | 37df7f2350b8cbe943fc075a68b41b8eb31d012e (diff) | |
download | mongo-7925d3e9a759e983a49cf44b90d58f77fbf7fb95.tar.gz |
SERVER-49108 Convert buildInfo command to async implementation
Diffstat (limited to 'src/mongo/executor')
-rw-r--r-- | src/mongo/executor/SConscript | 13 | ||||
-rw-r--r-- | src/mongo/executor/async_request_executor.cpp | 88 | ||||
-rw-r--r-- | src/mongo/executor/async_request_executor.h | 73 |
3 files changed, 174 insertions, 0 deletions
diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript index 2cb463484bd..de5ad45d9eb 100644 --- a/src/mongo/executor/SConscript +++ b/src/mongo/executor/SConscript @@ -280,6 +280,19 @@ env.Library( ], ) +env.Library( + target='async_request_executor', + source=[ + 'async_request_executor.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/service_context', + '$BUILD_DIR/mongo/util/concurrency/thread_pool', + '$BUILD_DIR/mongo/util/fail_point', + ], +) + env.CppUnitTest( target='executor_test', source=[ diff --git a/src/mongo/executor/async_request_executor.cpp b/src/mongo/executor/async_request_executor.cpp new file mode 100644 index 00000000000..cf535e864f6 --- /dev/null +++ b/src/mongo/executor/async_request_executor.cpp @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kExecutor + +#include "mongo/executor/async_request_executor.h" + +#include "mongo/db/client_strand.h" +#include "mongo/db/operation_context.h" +#include "mongo/logv2/log.h" +#include "mongo/platform/compiler.h" +#include "mongo/util/fail_point.h" + +namespace mongo { + +MONGO_FAIL_POINT_DEFINE(hangBeforeRunningAsyncRequestExecutorTask); + +AsyncRequestExecutor::AsyncRequestExecutor(std::string name) : _name(std::move(name)) { + ThreadPool::Options options; + options.minThreads = 0; + options.maxThreads = 1; + _pool = std::make_unique<ThreadPool>(std::move(options)); + _pool->startup(); + LOGV2_DEBUG( + 4910801, kDiagnosticLogLevel, "Started asynchronous request executor", "name"_attr = _name); +} + +AsyncRequestExecutor::~AsyncRequestExecutor() { + _pool->shutdown(); + _pool->join(); + LOGV2_DEBUG( + 4910802, kDiagnosticLogLevel, "Stopped asynchronous request executor", "name"_attr = _name); +} + +Future<void> AsyncRequestExecutor::schedule(std::shared_ptr<RequestExecutionContext> rec) { + auto opCtx = rec->getOpCtx(); + auto [promise, future] = makePromiseFuture<void>(); + + // `this` remains valid as it owns the instance of thread pool. + _pool->schedule([this, + strand = ClientStrand::get(opCtx->getClient()), + promise = std::move(promise), + rec = std::move(rec)](Status status) mutable { + hangBeforeRunningAsyncRequestExecutorTask.pauseWhileSet(); + strand->run([&] { + promise.setWith([&] { + if (MONGO_unlikely(!status.isOK())) + return status.withContext("Unable to schedule asynchronous request"); + + auto opCtx = rec->getOpCtx(); + if (opCtx->isKillPending()) + return Status(opCtx->getKillStatus(), "Asynchronous operation was interrupted"); + + return handleRequest(std::move(rec)); + }); + }); + }); + + return std::move(future); +} + +} // namespace mongo diff --git a/src/mongo/executor/async_request_executor.h b/src/mongo/executor/async_request_executor.h new file mode 100644 index 00000000000..a54e7848392 --- /dev/null +++ b/src/mongo/executor/async_request_executor.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include <memory> +#include <string> + +#include "mongo/db/request_execution_context.h" +#include "mongo/util/concurrency/thread_pool.h" +#include "mongo/util/future.h" + +namespace mongo { + +/** + * The base class for constructing command-specific asynchronous executors. + * Requests (i.e., instances of `RequestExecutionContext`) are scheduled on a thread-pool, and + * passed to the command-specific implementation of `handleRequest`. + */ +class AsyncRequestExecutor { +public: + AsyncRequestExecutor(AsyncRequestExecutor&&) = delete; + AsyncRequestExecutor(const AsyncRequestExecutor&) = delete; + + explicit AsyncRequestExecutor(std::string name); + ~AsyncRequestExecutor(); + + /** + * Runs the command-specific code to handle the request. + * Must only access the request on the corresponding client thread. + */ + virtual Status handleRequest(std::shared_ptr<RequestExecutionContext>) = 0; + + /** + * Schedules the request on a thread pool (i.e., `_pool`) and calls into `handleRequest` to + * asynchronously execute the command. + */ + Future<void> schedule(std::shared_ptr<RequestExecutionContext> rec); + + static constexpr auto kDiagnosticLogLevel = 4; + +private: + const std::string _name; + std::unique_ptr<ThreadPool> _pool; +}; + +} // namespace mongo |