/**
* 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/db/jsobj.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 _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);
// TODO: remove when StatusWith supports non-default constructible types (SERVER-18007)
ReadPreferenceSetting() = default;
inline bool equals(const ReadPreferenceSetting& other) const {
return (pref == other.pref) && (tags == other.tags);
}
/**
* 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: }. The 'mode' element must 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{ReadPreference::PrimaryOnly};
TagSet tags{TagSet::primaryOnly()};
};
} // namespace mongo