summaryrefslogtreecommitdiff
path: root/src/mongo/transport/service_executor.cpp
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@10gen.com>2020-08-17 19:02:48 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-31 16:41:08 +0000
commitb039b24746e1d1fb10a32e1ca4831423c01d4cd7 (patch)
treeb74d6034f40bbb97bfa336fdb480ee58892f9d3b /src/mongo/transport/service_executor.cpp
parentf5da4e4b7f7f04267bd92736ee9b16417e6d70ff (diff)
downloadmongo-b039b24746e1d1fb10a32e1ca4831423c01d4cd7.tar.gz
SERVER-48980 Associate ServiceExecutors with Clients
Diffstat (limited to 'src/mongo/transport/service_executor.cpp')
-rw-r--r--src/mongo/transport/service_executor.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/mongo/transport/service_executor.cpp b/src/mongo/transport/service_executor.cpp
new file mode 100644
index 00000000000..37c3d03e1b1
--- /dev/null
+++ b/src/mongo/transport/service_executor.cpp
@@ -0,0 +1,135 @@
+/**
+ * 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::kNetwork
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/transport/service_executor.h"
+
+#include <boost/optional.hpp>
+
+#include "mongo/logv2/log.h"
+#include "mongo/transport/service_entry_point.h"
+#include "mongo/transport/service_executor_fixed.h"
+#include "mongo/transport/service_executor_reserved.h"
+#include "mongo/transport/service_executor_synchronous.h"
+
+namespace mongo {
+namespace transport {
+namespace {
+static constexpr auto kDiagnosticLogLevel = 4;
+
+auto getServiceExecutorContext =
+ Client::declareDecoration<boost::optional<ServiceExecutorContext>>();
+} // namespace
+
+StringData toString(ServiceExecutorContext::ThreadingModel threadingModel) {
+ switch (threadingModel) {
+ case ServiceExecutorContext::ThreadingModel::kDedicated:
+ return "Dedicated"_sd;
+ case ServiceExecutorContext::ThreadingModel::kBorrowed:
+ return "Borrowed"_sd;
+ default:
+ MONGO_UNREACHABLE;
+ }
+}
+
+ServiceExecutorContext* ServiceExecutorContext::get(Client* client) noexcept {
+ auto& serviceExecutorContext = getServiceExecutorContext(client);
+
+ if (!serviceExecutorContext) {
+ // Service worker Clients will never have a ServiceExecutorContext.
+ return nullptr;
+ }
+
+ return &serviceExecutorContext.get();
+}
+
+void ServiceExecutorContext::set(Client* client, ServiceExecutorContext seCtx) noexcept {
+ auto& serviceExecutorContext = getServiceExecutorContext(client);
+ invariant(!serviceExecutorContext);
+
+ seCtx._client = client;
+ seCtx._sep = client->getServiceContext()->getServiceEntryPoint();
+
+ LOGV2_DEBUG(4898000,
+ kDiagnosticLogLevel,
+ "Setting initial ServiceExecutor context for client",
+ "client"_attr = client->desc(),
+ "threadingModel"_attr = seCtx._threadingModel,
+ "canUseReserved"_attr = seCtx._canUseReserved);
+ serviceExecutorContext = std::move(seCtx);
+}
+
+ServiceExecutorContext& ServiceExecutorContext::setThreadingModel(
+ ThreadingModel threadingModel) noexcept {
+ _threadingModel = threadingModel;
+ return *this;
+}
+
+ServiceExecutorContext& ServiceExecutorContext::setCanUseReserved(bool canUseReserved) noexcept {
+ _canUseReserved = canUseReserved;
+ return *this;
+}
+
+ServiceExecutor* ServiceExecutorContext::getServiceExecutor() const noexcept {
+ invariant(_client);
+
+ switch (_threadingModel) {
+ case ThreadingModel::kBorrowed:
+ return ServiceExecutorFixed::get(_client->getServiceContext());
+ case ThreadingModel::kDedicated: {
+ // Continue on.
+ } break;
+ default:
+ MONGO_UNREACHABLE;
+ }
+
+ auto shouldUseReserved = [&] {
+ // This is at best a naive solution. There could be a world where numOpenSessions() changes
+ // very quickly. We are not taking locks on the ServiceEntryPoint, so we may chose to
+ // schedule onto the ServiceExecutorReserved when it is no longer necessary. The upside is
+ // that we will automatically shift to the ServiceExecutorSynchronous after the first
+ // command loop.
+ return _sep->numOpenSessions() > _sep->maxOpenSessions();
+ };
+
+ if (_canUseReserved && shouldUseReserved()) {
+ if (auto exec = transport::ServiceExecutorReserved::get(_client->getServiceContext())) {
+ // We are allowed to use the reserved executor, we should use it, and it exists.
+ return exec;
+ }
+ }
+
+ return transport::ServiceExecutorSynchronous::get(_client->getServiceContext());
+}
+
+} // namespace transport
+} // namespace mongo