/**
* Copyright (C) 2015 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* 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 GNU Affero General 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 "mongo/bson/simple_bsonobj_comparator.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/repl/optime.h"
#include "mongo/util/duration.h"
namespace mongo {
template
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,
/**
* Read from a secondary if available, otherwise read from the primary.
*/
SecondaryPreferred,
/**
* Read from any member.
*/
Nearest,
};
/**
* A simple object for representing the list of tags requested by a $readPreference.
*/
class TagSet {
public:
/**
* Creates a TagSet that matches any nodes. This is the TagSet represented by the BSON
* array containing a single empty document - [{}].
*
* Do not call during static init.
*/
TagSet();
/**
* Returns an empty TagSet. This is the TagSet represented by the empty BSON array - [].
* This TagSet must be associated with ReadPreference::PrimaryOnly.
* ReadPreference::Primary.
*/
static TagSet primaryOnly();
/**
* Creates a TagSet from a BSONArray of tags.
*
* @param tags the list of tags associated with this option. This object
* will get a shared copy of the list. Therefore, it is important
* for the the given tag to live longer than the created tag set.
*/
explicit TagSet(const BSONArray& tags) : _tags(tags) {}
/**
* Returns the BSONArray listing all tags that should be accepted.
*/
const BSONArray& getTagBSON() const {
return _tags;
}
bool operator==(const TagSet& other) const {
return SimpleBSONObjComparator::kInstance.evaluate(_tags == other._tags);
}
bool operator!=(const TagSet& other) const {
return !(*this == other);
}
private:
BSONArray _tags;
};
struct ReadPreferenceSetting {
/**
* @param pref the read preference mode.
* @param tag the tag set. Note that this object will have the
* tag set will have this in a reset state (meaning, this
* object's copy of tag will have the iterator in the initial
* position).
*/
ReadPreferenceSetting(ReadPreference pref, TagSet tags, Seconds maxStalenessSeconds);
ReadPreferenceSetting(ReadPreference pref, Seconds maxStalenessSeconds);
ReadPreferenceSetting(ReadPreference pref, TagSet tags);
explicit ReadPreferenceSetting(ReadPreference pref);
inline bool equals(const ReadPreferenceSetting& other) const {
return (pref == other.pref) && (tags == other.tags) &&
(maxStalenessSeconds == other.maxStalenessSeconds) && (minOpTime == other.minOpTime);
}
/**
* Serializes this ReadPreferenceSetting as a BSON document.
*/
BSONObj toBSON() const;
/**
* Describes this ReadPreferenceSetting as a string.
*/
std::string toString() const;
/**
* Parses a ReadPreferenceSetting from a BSON document of the form:
* { mode: , tags: , maxStalenessSeconds: Number }. The 'mode' element must
* be a string equal to either "primary", "primaryPreferred", "secondary", "secondaryPreferred",
* or "nearest". Although the tags array is intended to be an array of unique BSON documents, no
* further validation is performed on it other than checking that it is an array, and that it is
* empty if 'mode' is 'primary'.
*/
static StatusWith fromBSON(const BSONObj& readPrefSettingObj);
ReadPreference pref;
TagSet tags;
Seconds maxStalenessSeconds{};
repl::OpTime minOpTime{};
/**
* The minimal value maxStalenessSeconds can have.
*/
static const Seconds kMinimalMaxStalenessValue;
};
} // namespace mongo