summaryrefslogtreecommitdiff
path: root/src/mongo/client/read_preference.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-11-14 14:13:03 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-11-15 10:08:45 -0500
commit21821549cdeef84173293c46725695fc3a7834b0 (patch)
treea6d68779f04e83e289d036418d20087522e09d1b /src/mongo/client/read_preference.cpp
parent19449d2883f2a97b622102935a63606d950573ad (diff)
downloadmongo-21821549cdeef84173293c46725695fc3a7834b0.tar.gz
SERVER-26927 Rename maxStalenessMS to maxStalenessSeconds and support doubles
Diffstat (limited to 'src/mongo/client/read_preference.cpp')
-rw-r--r--src/mongo/client/read_preference.cpp70
1 files changed, 46 insertions, 24 deletions
diff --git a/src/mongo/client/read_preference.cpp b/src/mongo/client/read_preference.cpp
index 5df64eab171..ea16f3365ad 100644
--- a/src/mongo/client/read_preference.cpp
+++ b/src/mongo/client/read_preference.cpp
@@ -46,7 +46,7 @@ namespace {
const char kModeFieldName[] = "mode";
const char kTagsFieldName[] = "tags";
-const char kMaxStalenessMSFieldName[] = "maxStalenessMS";
+const char kMaxStalenessSecondsFieldName[] = "maxStalenessSeconds";
const char kPrimaryOnly[] = "primary";
const char kPrimaryPreferred[] = "primaryPreferred";
@@ -54,6 +54,9 @@ const char kSecondaryOnly[] = "secondary";
const char kSecondaryPreferred[] = "secondaryPreferred";
const char kNearest[] = "nearest";
+// Avoid overflow errors when converting from seconds to milliseconds
+const auto kMaximalMaxStalenessSecondsValue(durationCount<Seconds>(Milliseconds::max()));
+
StringData readPreferenceName(ReadPreference pref) {
switch (pref) {
case ReadPreference::PrimaryOnly:
@@ -182,39 +185,56 @@ StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromBSON(const BSONObj&
return tagExtractStatus;
}
- long long maxStalenessMSValue;
- auto maxStalenessMSExtractStatus = bsonExtractIntegerFieldWithDefault(
- readPrefObj, kMaxStalenessMSFieldName, 0, &maxStalenessMSValue);
+ double maxStalenessSecondsValue;
+
+ Status maxStalenessSecondsExtractStatus = bsonExtractDoubleField(
+ readPrefObj, kMaxStalenessSecondsFieldName, &maxStalenessSecondsValue);
+
+ if (maxStalenessSecondsExtractStatus == ErrorCodes::NoSuchKey) {
+ return ReadPreferenceSetting(mode, tags);
+ } else if (!maxStalenessSecondsExtractStatus.isOK()) {
+ return maxStalenessSecondsExtractStatus;
+ }
- if (!maxStalenessMSExtractStatus.isOK()) {
- return maxStalenessMSExtractStatus;
+ if (maxStalenessSecondsValue < 0.0) {
+ return {ErrorCodes::BadValue,
+ str::stream() << kMaxStalenessSecondsFieldName << " value can not be negative"};
}
- if (maxStalenessMSValue && maxStalenessMSValue < 0) {
- return Status(ErrorCodes::BadValue,
- str::stream() << kMaxStalenessMSFieldName
- << " must be a non negative integer");
+ if (maxStalenessSecondsValue > kMaximalMaxStalenessSecondsValue) {
+ return {ErrorCodes::MaxStalenessOutOfRange,
+ str::stream() << kMaxStalenessSecondsFieldName << " value can not exceed "
+ << kMaximalMaxStalenessSecondsValue};
}
- if (maxStalenessMSValue && maxStalenessMSValue >= Milliseconds::max().count()) {
- return Status(ErrorCodes::BadValue,
- str::stream() << kMaxStalenessMSFieldName << " value can not exceed "
- << Milliseconds::max().count());
+ if (maxStalenessSecondsValue == 0.0) {
+ return ReadPreferenceSetting(mode, tags);
}
- if (maxStalenessMSValue && maxStalenessMSValue < kMinimalMaxStalenessValue.count()) {
- return Status(ErrorCodes::MaxStalenessOutOfRange,
- str::stream() << kMaxStalenessMSFieldName << " value can not be less than "
- << kMinimalMaxStalenessValue.count());
+ // Use a lambda to do the double seconds to integer milliseconds conversion in order to
+ // encapsulate the usage of helper variables
+ const Milliseconds requestedMaxStalenessMS = [maxStalenessSecondsValue] {
+ double integerPart;
+ const double fractionalPart = std::modf(maxStalenessSecondsValue, &integerPart);
+
+ return Seconds(static_cast<long long>(integerPart)) +
+ Milliseconds(static_cast<long long>(fractionalPart *
+ durationCount<Milliseconds>(Seconds(1))));
+ }();
+
+ if (requestedMaxStalenessMS < kMinimalMaxStalenessValue) {
+ return {ErrorCodes::MaxStalenessOutOfRange,
+ str::stream() << kMaxStalenessSecondsFieldName << " value can not be less than "
+ << kMinimalMaxStalenessValue};
}
- if ((mode == ReadPreference::PrimaryOnly) && maxStalenessMSValue) {
- return Status(ErrorCodes::BadValue,
- str::stream() << kMaxStalenessMSFieldName
- << " can not be set for the primary mode");
+ if (mode == ReadPreference::PrimaryOnly) {
+ return {ErrorCodes::BadValue,
+ str::stream() << kMaxStalenessSecondsFieldName
+ << " can not be set for the primary mode"};
}
- return ReadPreferenceSetting(mode, tags, Milliseconds(maxStalenessMSValue));
+ return ReadPreferenceSetting(mode, tags, requestedMaxStalenessMS);
}
BSONObj ReadPreferenceSetting::toBSON() const {
@@ -224,7 +244,9 @@ BSONObj ReadPreferenceSetting::toBSON() const {
bob.append(kTagsFieldName, tags.getTagBSON());
}
if (maxStalenessMS.count() > 0) {
- bob.append(kMaxStalenessMSFieldName, maxStalenessMS.count());
+ bob.append(kMaxStalenessSecondsFieldName,
+ static_cast<double>(maxStalenessMS.count()) /
+ durationCount<Milliseconds>(Seconds(1)));
}
return bob.obj();
}