summaryrefslogtreecommitdiff
path: root/src/mongo/client
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@10gen.com>2020-03-17 23:24:28 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-18 17:58:52 +0000
commit7296a460f826c8a618147e09606c5f1935c482a4 (patch)
treedc9965f86a0ec9bae66636c818a500170dfbd422 /src/mongo/client
parent03dc2fefa0fb1c77d2caeb6dd166166276bc5b15 (diff)
downloadmongo-7296a460f826c8a618147e09606c5f1935c482a4.tar.gz
SERVER-38731 Implement ability to specify sync source read preference in initial sync
Diffstat (limited to 'src/mongo/client')
-rw-r--r--src/mongo/client/SConscript1
-rw-r--r--src/mongo/client/read_preference.cpp69
-rw-r--r--src/mongo/client/read_preference.h34
-rw-r--r--src/mongo/client/read_preference.idl56
4 files changed, 84 insertions, 76 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript
index 8d216c960d5..51c3df426c9 100644
--- a/src/mongo/client/SConscript
+++ b/src/mongo/client/SConscript
@@ -33,6 +33,7 @@ env.Library(
source=[
'read_preference.cpp',
env.Idlc('hedging_mode.idl')[0],
+ env.Idlc('read_preference.idl')[0],
],
LIBDEPS=[
'$BUILD_DIR/mongo/bson/util/bson_extract',
diff --git a/src/mongo/client/read_preference.cpp b/src/mongo/client/read_preference.cpp
index 5c686a839c6..3d52248f223 100644
--- a/src/mongo/client/read_preference.cpp
+++ b/src/mongo/client/read_preference.cpp
@@ -50,49 +50,6 @@ const char kTagsFieldName[] = "tags";
const char kMaxStalenessSecondsFieldName[] = "maxStalenessSeconds";
const char kHedgeFieldName[] = "hedge";
-const char kPrimaryOnly[] = "primary";
-const char kPrimaryPreferred[] = "primaryPreferred";
-const char kSecondaryOnly[] = "secondary";
-const char kSecondaryPreferred[] = "secondaryPreferred";
-const char kNearest[] = "nearest";
-
-StringData readPreferenceName(ReadPreference pref) {
- switch (pref) {
- case ReadPreference::PrimaryOnly:
- return StringData(kPrimaryOnly);
- case ReadPreference::PrimaryPreferred:
- return StringData(kPrimaryPreferred);
- case ReadPreference::SecondaryOnly:
- return StringData(kSecondaryOnly);
- case ReadPreference::SecondaryPreferred:
- return StringData(kSecondaryPreferred);
- case ReadPreference::Nearest:
- return StringData(kNearest);
- default:
- MONGO_UNREACHABLE;
- }
-}
-
-StatusWith<ReadPreference> parseReadPreferenceMode(StringData prefStr) {
- if (prefStr == kPrimaryOnly) {
- return ReadPreference::PrimaryOnly;
- } else if (prefStr == kPrimaryPreferred) {
- return ReadPreference::PrimaryPreferred;
- } else if (prefStr == kSecondaryOnly) {
- return ReadPreference::SecondaryOnly;
- } else if (prefStr == kSecondaryPreferred) {
- return ReadPreference::SecondaryPreferred;
- } else if (prefStr == kNearest) {
- return ReadPreference::Nearest;
- }
- return Status(ErrorCodes::FailedToParse,
- str::stream() << "Could not parse $readPreference mode '" << prefStr
- << "'. Only the modes '" << kPrimaryOnly << "', '"
- << kPrimaryPreferred << "', '" << kSecondaryOnly << "', '"
- << kSecondaryPreferred << "', and '" << kNearest
- << "' are supported.");
-}
-
// Slight kludge here: if we weren't passed a TagSet, we default to the empty
// TagSet if ReadPreference is Primary, or the default (wildcard) TagSet otherwise.
// This maintains compatibility with existing code, while preserving the ability to round
@@ -108,6 +65,14 @@ TagSet defaultTagSetForMode(ReadPreference mode) {
} // namespace
+Status validateReadPreferenceMode(const std::string& prefStr) {
+ try {
+ ReadPreference_parse(IDLParserErrorContext(kModeFieldName), prefStr);
+ } catch (DBException& e) {
+ return e.toStatus();
+ }
+ return Status::OK();
+}
/**
* Replica set refresh period on the task executor.
@@ -157,11 +122,19 @@ StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromInnerBSON(const BSO
}
ReadPreference mode;
- auto swReadPrefMode = parseReadPreferenceMode(modeStr);
- if (!swReadPrefMode.isOK()) {
- return swReadPrefMode.getStatus();
+ try {
+ mode = ReadPreference_parse(IDLParserErrorContext(kModeFieldName), modeStr);
+ } catch (DBException& e) {
+ return e.toStatus().withContext(
+ str::stream() << "Could not parse $readPreference mode '" << modeStr
+ << "'. Only the modes '"
+ << ReadPreference_serializer(ReadPreference::PrimaryOnly) << "', '"
+ << ReadPreference_serializer(ReadPreference::PrimaryPreferred) << "', '"
+ << ReadPreference_serializer(ReadPreference::SecondaryOnly) << "', '"
+ << ReadPreference_serializer(ReadPreference::SecondaryPreferred)
+ << "', and '" << ReadPreference_serializer(ReadPreference::Nearest)
+ << "' are supported.");
}
- mode = std::move(swReadPrefMode.getValue());
boost::optional<HedgingMode> hedgingMode;
if (auto hedgingModeEl = readPrefObj[kHedgeFieldName]) {
@@ -261,7 +234,7 @@ StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromContainingBSON(
}
void ReadPreferenceSetting::toInnerBSON(BSONObjBuilder* bob) const {
- bob->append(kModeFieldName, readPreferenceName(pref));
+ bob->append(kModeFieldName, ReadPreference_serializer(pref));
if (tags != defaultTagSetForMode(pref)) {
bob->append(kTagsFieldName, tags.getTagBSON());
}
diff --git a/src/mongo/client/read_preference.h b/src/mongo/client/read_preference.h
index 5ab06c6f397..5d003ec276a 100644
--- a/src/mongo/client/read_preference.h
+++ b/src/mongo/client/read_preference.h
@@ -31,6 +31,7 @@
#include "mongo/bson/simple_bsonobj_comparator.h"
#include "mongo/client/hedging_mode_gen.h"
+#include "mongo/client/read_preference_gen.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/optime.h"
@@ -40,35 +41,12 @@ namespace mongo {
template <typename T>
class StatusWith;
-enum class ReadPreference {
- /**
- * Read from primary only. All operations produce an error (throw an exception where
- * applicable) if primary is unavailable. Cannot be combined with tags.
- */
- PrimaryOnly = 0,
-
- /**
- * Read from primary if available, otherwise a secondary. Tags will only be applied in the
- * event that the primary is unavailable and a secondary is read from. In this event only
- * secondaries matching the tags provided would be read from.
- */
- PrimaryPreferred,
-
- /**
- * Read from secondary if available, otherwise error.
- */
- SecondaryOnly,
+using ReadPreference = ReadPreferenceEnum;
- /**
- * Read from a secondary if available, otherwise read from the primary.
- */
- SecondaryPreferred,
-
- /**
- * Read from any member.
- */
- Nearest,
-};
+/**
+ * Validate a ReadPreference string. This is intended for use as an IDL validator callback.
+ */
+Status validateReadPreferenceMode(const std::string& prefStr);
/**
* A simple object for representing the list of tags requested by a $readPreference.
diff --git a/src/mongo/client/read_preference.idl b/src/mongo/client/read_preference.idl
new file mode 100644
index 00000000000..d98376baef8
--- /dev/null
+++ b/src/mongo/client/read_preference.idl
@@ -0,0 +1,56 @@
+# 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.
+#
+
+global:
+ cpp_namespace: "mongo"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+
+enums:
+ ReadPreference:
+ description: Enumeration representing Read Preference Modes
+ type: string
+ values:
+ # Read from primary only. All operations produce an error (throw an exception where
+ # applicable) if primary is unavailable. Cannot be combined with tags.
+ PrimaryOnly: "primary"
+ #
+ # Read from primary if available, otherwise a secondary. Tags will only be applied in the
+ # event that the primary is unavailable and a secondary is read from. In this event only
+ # secondaries matching the tags provided would be read from.
+ PrimaryPreferred: "primaryPreferred"
+ #
+ # Read from secondary if available, otherwise error.
+ SecondaryOnly: "secondary"
+ #
+ # Read from a secondary if available, otherwise read from the primary.
+ SecondaryPreferred: "secondaryPreferred"
+ #
+ # Read from any member.
+ Nearest: "nearest"