diff options
author | Sanika Phanse <sanika.phanse@mongodb.com> | 2022-04-12 18:36:32 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-12 23:44:20 +0000 |
commit | 84467ea62f22f10137fa919a4c019afbac6ac63b (patch) | |
tree | 1b047144210be72d7758aea85902d4c58da779f6 /src/mongo/s | |
parent | 673e9e2290ac6a792fa95d34167c6d2bbec4b6c4 (diff) | |
download | mongo-84467ea62f22f10137fa919a4c019afbac6ac63b.tar.gz |
SERVER-63081 Create a test command for internal transactions
Diffstat (limited to 'src/mongo/s')
-rw-r--r-- | src/mongo/s/commands/SConscript | 6 | ||||
-rw-r--r-- | src/mongo/s/commands/internal_transactions_test_command.h (renamed from src/mongo/s/commands/internal_transactions_test_commands.cpp) | 79 | ||||
-rw-r--r-- | src/mongo/s/commands/internal_transactions_test_command_s.cpp | 50 | ||||
-rw-r--r-- | src/mongo/s/commands/internal_transactions_test_commands.idl | 74 |
4 files changed, 101 insertions, 108 deletions
diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript index 91a07c18245..be0eb7d5203 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -12,15 +12,10 @@ env.Library( source=[ 'flush_router_config_cmd.cpp', 'get_shard_map_cmd.cpp', - 'internal_transactions_test_commands.cpp', - 'internal_transactions_test_commands.idl', ], LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/db/cluster_transaction_api', '$BUILD_DIR/mongo/db/commands', - '$BUILD_DIR/mongo/db/transaction_api', '$BUILD_DIR/mongo/s/grid', - '$BUILD_DIR/mongo/s/sharding_router_api', '$BUILD_DIR/mongo/s/startup_initialization', ] ) @@ -98,6 +93,7 @@ env.Library( 'cluster_validate_db_metadata_cmd.cpp', 'cluster_whats_my_uri_cmd.cpp', 'cluster_write_cmd_s.cpp', + 'internal_transactions_test_command_s.cpp', 'kill_sessions_remote.cpp', 'refine_collection_shard_key.idl', 's_read_write_concern_defaults_server_status.cpp', diff --git a/src/mongo/s/commands/internal_transactions_test_commands.cpp b/src/mongo/s/commands/internal_transactions_test_command.h index 1843dd9c28e..dc4b7fc00c8 100644 --- a/src/mongo/s/commands/internal_transactions_test_commands.cpp +++ b/src/mongo/s/commands/internal_transactions_test_command.h @@ -30,40 +30,28 @@ #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/cluster_transaction_api.h" #include "mongo/db/commands.h" +#include "mongo/db/commands/internal_transactions_test_command_gen.h" #include "mongo/db/query/find_command_gen.h" #include "mongo/db/transaction_api.h" #include "mongo/logv2/log.h" -#include "mongo/s/commands/internal_transactions_test_commands_gen.h" #include "mongo/s/grid.h" -#include "mongo/s/transaction_router_resource_yielder.h" +#include "mongo/stdx/future.h" namespace mongo { namespace { -class InternalTransactionsTestCommand final : public TypedCommand<InternalTransactionsTestCommand> { +template <typename Impl> +class InternalTransactionsTestCommandBase : public TypedCommand<Impl> { public: using Request = TestInternalTransactions; - class Invocation final : public InvocationBase { + class Invocation final : public TypedCommand<Impl>::InvocationBase { public: - using InvocationBase::InvocationBase; - - TestInternalTransactionsReply typedRun(OperationContext* opCtx) { - Grid::get(opCtx)->assertShardingIsInitialized(); - - auto fixedExec = Grid::get(opCtx)->getExecutorPool()->getFixedExecutor(); - auto txn = txn_api::TransactionWithRetries( - opCtx, - fixedExec, - std::make_unique<txn_api::details::SEPTransactionClient>( - opCtx, - fixedExec, - std::make_unique<txn_api::details::ClusterSEPTransactionClientBehaviors>( - opCtx->getServiceContext())), - TransactionRouterResourceYielder::makeForLocalHandoff()); + using Base = typename TypedCommand<Impl>::InvocationBase; + using Base::Base; + TestInternalTransactionsCommandReply typedRun(OperationContext* opCtx) { struct SharedBlock { SharedBlock(std::vector<TestInternalTransactionsCommandInfo> commandInfos_) : commandInfos(commandInfos_) {} @@ -71,13 +59,29 @@ public: std::vector<TestInternalTransactionsCommandInfo> commandInfos; std::vector<BSONObj> responses; }; - auto sharedBlock = std::make_shared<SharedBlock>(request().getCommandInfos()); + + auto sharedBlock = std::make_shared<SharedBlock>(Base::request().getCommandInfos()); + + const auto executor = Grid::get(opCtx)->isShardingInitialized() + ? static_cast<ExecutorPtr>(Grid::get(opCtx)->getExecutorPool()->getFixedExecutor()) + : static_cast<ExecutorPtr>(getTransactionExecutor()); + + // If internalTransactionsTestCommand is received by a mongod, it should be instantiated + // with the TransactionParticipant's resource yielder. If on a mongos, txn should be + // instantiated with the TransactionRouter's resource yielder. + auto txn = Impl::getTxn(opCtx, + std::move(executor), + Base::request().kCommandName, + Base::request().getUseClusterClient()); // Swallow errors and let clients inspect the responses array to determine success / // failure. (void)txn.runSyncNoThrow( opCtx, [sharedBlock](const txn_api::TransactionClient& txnClient, ExecutorPtr txnExec) { + // Iterate through commands and record responses for each. Return immediately if + // we encounter a response with a retriedStmtId. This field indicates that the + // command and everything following it have already been executed. for (const auto& commandInfo : sharedBlock->commandInfos) { const auto& dbName = commandInfo.getDbName(); const auto& command = commandInfo.getCommand(); @@ -101,26 +105,27 @@ public: continue; } - auto res = txnClient.runCommand(dbName, command).get(); + const auto res = txnClient.runCommand(dbName, command).get(); sharedBlock->responses.emplace_back( CommandHelpers::filterCommandReplyForPassthrough( res.removeField("recoveryToken"))); + // TODO SERVER-64986: Remove assert check. if (assertSucceeds) { // Note this only inspects the top level ok field for non-write // commands. uassertStatusOK(getStatusFromWriteCommandReply(res)); } + // TODO SERVER-65048: Check if result has retriedStmtId & retriedStmtIds + // field, exit. } - return SemiFuture<void>::makeReady(); }); - - return TestInternalTransactionsReply(std::move(sharedBlock->responses)); + return TestInternalTransactionsCommandReply(std::move(sharedBlock->responses)); }; NamespaceString ns() const override { - return NamespaceString(request().getDbName(), ""); + return NamespaceString(Base::request().getDbName(), ""); } bool supportsWriteConcern() const override { @@ -134,6 +139,23 @@ public: ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), ActionType::internal)); } + + const std::shared_ptr<ThreadPool>& getTransactionExecutor() { + static Mutex mutex = + MONGO_MAKE_LATCH("InternalTransactionsTestCommandExecutor::_mutex"); + static std::shared_ptr<ThreadPool> executor; + + stdx::lock_guard<Latch> lg(mutex); + if (!executor) { + ThreadPool::Options options; + options.poolName = "InternalTransaction"; + options.minThreads = 0; + options.maxThreads = 4; + executor = std::make_shared<ThreadPool>(std::move(options)); + executor->startup(); + } + return executor; + } }; std::string help() const override { @@ -146,11 +168,10 @@ public: return true; } - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kNever; + BasicCommand::AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return BasicCommand::AllowedOnSecondary::kNever; } }; -MONGO_REGISTER_TEST_COMMAND(InternalTransactionsTestCommand); } // namespace } // namespace mongo diff --git a/src/mongo/s/commands/internal_transactions_test_command_s.cpp b/src/mongo/s/commands/internal_transactions_test_command_s.cpp new file mode 100644 index 00000000000..16f141fb5e3 --- /dev/null +++ b/src/mongo/s/commands/internal_transactions_test_command_s.cpp @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2022-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. + */ + +#include "mongo/s/commands/internal_transactions_test_command.h" +#include "mongo/s/transaction_router_resource_yielder.h" + +namespace mongo { +namespace { + +class InternalTransactionsTestCommandS + : public InternalTransactionsTestCommandBase<InternalTransactionsTestCommandS> { +public: + static txn_api::TransactionWithRetries getTxn(OperationContext* opCtx, + ExecutorPtr executor, + StringData commandName, + bool useClusterClient) { + return txn_api::TransactionWithRetries( + opCtx, executor, TransactionRouterResourceYielder::makeForLocalHandoff()); + } +}; + +MONGO_REGISTER_TEST_COMMAND(InternalTransactionsTestCommandS); +} // namespace +} // namespace mongo diff --git a/src/mongo/s/commands/internal_transactions_test_commands.idl b/src/mongo/s/commands/internal_transactions_test_commands.idl deleted file mode 100644 index 1e68776ba94..00000000000 --- a/src/mongo/s/commands/internal_transactions_test_commands.idl +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (C) 2022-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. -# - -global: - cpp_namespace: "mongo" - -imports: - - "mongo/idl/basic_types.idl" - -structs: - TestInternalTransactionsReply: - description: "Response for testInternalTransactions command" - strict: false - fields: - responses: - type: array<object> - - TestInternalTransactionsCommandInfo: - description: "A command, its database name, and other test options" - strict: false - fields: - dbName: - type: string - command: - type: object - assertSucceeds: - type: bool - default: true - exhaustCursor: - type: bool - optional: true - -commands: - testInternalTransactions: - command_name: testInternalTransactions - description: "The 'testInternalTransactions' command." - namespace: ignored - api_version: "" - fields: - useClusterClient: - description: "Whether the transaction API client used should opt into running the - 'cluster' versions of commands that enables a non-router node to run - the router versions of commands. Only meaningful on mongod because a - mongos will always run 'cluster' commands." - type: bool - default: false - commandInfos: - type: array<TestInternalTransactionsCommandInfo> - reply_type: TestInternalTransactionsReply |