MongoDB C++ Driver legacy-1.1.2
Loading...
Searching...
No Matches
replica_set_monitor_internal.h
1/* Copyright 2014 MongoDB Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
22#pragma once
23
24#include <boost/thread/condition_variable.hpp>
25#include <deque>
26#include <set>
27#include <string>
28#include <vector>
29
30#include "mongo/base/disallow_copying.h"
31#include "mongo/client/dbclient_rs.h" // for TagSet and ReadPreferenceSettings
32#include "mongo/client/replica_set_monitor.h"
33#include "mongo/db/jsobj.h"
34#include "mongo/platform/cstdint.h"
35#include "mongo/platform/random.h"
36#include "mongo/platform/unordered_map.h"
37#include "mongo/util/net/hostandport.h"
38
39namespace mongo {
40// Internal connection cache for isMaster. Used to amortize the cost of establishing connections
41// to a remote host. Not really a pool because we only keep one connection per host.
43public:
44 // Uses a cached connection (may need to reconnect) to execute a remote isMaster call
45 // on the given host. Returns microseconds taken for remote call to complete. Throws.
46 uint64_t timedIsMaster(const HostAndPort& host, BSONObj* out);
47
48private:
49 typedef unordered_map<HostAndPort, boost::shared_ptr<DBClientConnection> > ConnectionMap;
50
51 // Guard that creates a connection if needed, or removes it from
52 // the cache. This is so multiple isMaster calls can be in flight in the same
53 // set simultaneously.
54 class ConnectionGuard {
55 public:
56 // Lifetime of guard must be subset of lifetime of host
57 ConnectionGuard(ConnectionCache& cache, const HostAndPort& host)
58 : _cache(cache), _host(host) {
59 // this could throw.
60 _conn = _cache.getConnectionTo(_host);
61 }
62
63 ~ConnectionGuard() {
64 _cache.returnConnection(_host, _conn);
65 }
66
67 boost::shared_ptr<DBClientConnection> _conn;
68 // Reference to owner.
69 ConnectionCache& _cache;
70 const HostAndPort& _host;
71 };
72
73 // If we don't have a connection to this host cached,
74 // or we have one that is dead, we reconnect and return
75 // If we have one, we remove it from the cache and return it
76 boost::shared_ptr<DBClientConnection> getConnectionTo(const HostAndPort& host);
77
78 void returnConnection(const HostAndPort& host, boost::shared_ptr<DBClientConnection> conn);
79
80 inline bool connectionOk(const boost::shared_ptr<DBClientConnection>& conn) {
81 // checks are ordered from cheap to expensive
82 return conn && !conn->isFailed() && conn->isStillConnected();
83 }
84
85 ConnectionMap _cacheStorage;
86 boost::mutex _cacheLock;
87};
88
90 IsMasterReply() : ok(false) {}
91 IsMasterReply(const HostAndPort& host, int64_t latencyMicros, const BSONObj& reply)
92 : ok(false), host(host), latencyMicros(latencyMicros) {
93 parse(reply);
94 }
95
99 void parse(const BSONObj& obj);
100
101 bool ok; // if false, ignore all other fields
102 BSONObj raw; // Always owned. Other fields are allowed to be a view into this.
103 std::string setName;
104 bool isMaster;
105 bool secondary;
106 bool hidden;
107 OID electionId; // Set if this isMaster reply is from the primary
108 HostAndPort primary; // empty if not present
109 std::set<HostAndPort> normalHosts; // both "hosts" and "passives"
110 BSONObj tags;
111
112 // remaining fields aren't in isMaster reply, but are known to caller.
113 HostAndPort host;
114 int64_t latencyMicros; // ignored if negative
115};
116
118 MONGO_DISALLOW_COPYING(SetState);
119
120public:
121 // A single node in the replicaSet
122 struct Node {
123 explicit Node(const HostAndPort& host) : host(host), latencyMicros(unknownLatency) {
124 markFailed();
125 }
126
127 void markFailed() {
128 isUp = false;
129 isMaster = false;
130 }
131
132 bool matches(const ReadPreference& pref) const;
133
147 bool matches(const BSONObj& tag) const;
148
152 void update(const IsMasterReply& reply);
153
154 // Intentionally chosen to compare worse than all known latencies.
155 static const int64_t unknownLatency; // = numeric_limits<int64_t>::max()
156
157 HostAndPort host;
158 bool isUp;
159 bool isMaster; // implies isUp
160 int64_t latencyMicros; // unknownLatency if unknown
161 BSONObj tags; // owned
162 };
163 typedef std::vector<Node> Nodes;
164
168 SetState(StringData name, const std::set<HostAndPort>& seedNodes);
169
176
180 Node* findNode(const HostAndPort& host);
181
187
188 void updateNodeIfInNodes(const IsMasterReply& reply);
189
190 std::string getServerAddress() const;
191
195 void checkInvariants() const;
196
197 static ConfigChangeHook configChangeHook;
198
199 boost::mutex mutex; // must hold this to access any other member or method (except name).
200
201 // If Refresher::getNextStep returns WAIT, you should wait on the condition_variable,
202 // releasing mutex. It will be notified when either getNextStep will return something other
203 // than WAIT, or a new host is available for consideration by getMatchingHost. Essentially,
204 // this will be hit whenever the _refreshUntilMatches loop has the potential to make
205 // progress.
206 // TODO consider splitting cv into two: one for when looking for a master, one for all other
207 // cases.
208 boost::condition_variable cv;
209
210 const std::string name; // safe to read outside lock since it is const
211 int consecutiveFailedScans;
212 std::set<HostAndPort> seedNodes; // updated whenever a master reports set membership changes
213 OID maxElectionId; // largest election id observed by this ReplicaSetMonitor
214 HostAndPort lastSeenMaster; // empty if we have never seen a master. can be same as current
215 Nodes nodes; // maintained sorted and unique by host
216 ScanStatePtr currentScan; // NULL if no scan in progress
217 int64_t latencyThresholdMicros;
218 mutable PseudoRandom rand; // only used for host selection to balance load
219 mutable int roundRobin; // used when useDeterministicHostSelection is true
220 mutable ConnectionCache connectionCache;
221};
222
224 MONGO_DISALLOW_COPYING(ScanState);
225
226public:
227 ScanState() : foundUpMaster(false), foundAnyUpNodes(false) {}
228
233 template <typename Container>
234 void enqueAllUntriedHosts(const Container& container, PseudoRandom& rand);
235
236 // Access to fields is guarded by associated SetState's mutex.
237 bool foundUpMaster;
238 bool foundAnyUpNodes;
239 std::deque<HostAndPort> hostsToScan; // Work queue.
240 std::set<HostAndPort> possibleNodes; // Nodes reported by non-primary hosts.
241 std::set<HostAndPort> waitingFor; // Hosts we have dispatched but haven't replied yet.
242 std::set<HostAndPort> triedHosts; // Hosts that have been returned from getNextStep.
243
244 // All responses go here until we find a master.
245 typedef std::vector<IsMasterReply> UnconfirmedReplies;
246 UnconfirmedReplies unconfirmedReplies;
247};
248}
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition bsonobj.h:78
Definition replica_set_monitor_internal.h:42
Object ID type.
Definition oid.h:60
Uses http://en.wikipedia.org/wiki/Xorshift.
Definition random.h:27
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents.
Definition string_data.h:43
Connect to a Replica Set, from C++.
BSON classes.
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:20
Name of a process on the network.
Definition hostandport.h:37
Definition dbclient_rs.h:363
Definition replica_set_monitor_internal.h:89
void parse(const BSONObj &obj)
Never throws.
Definition replica_set_monitor_internal.h:223
void enqueAllUntriedHosts(const Container &container, PseudoRandom &rand)
Adds all hosts in container that aren't in triedHosts to hostsToScan, then shuffles the queue.
Definition replica_set_monitor_internal.h:122
bool matches(const BSONObj &tag) const
Checks if the given tag matches the tag attached to this node.
void update(const IsMasterReply &reply)
Updates this Node based on information in reply.
Definition replica_set_monitor_internal.h:117
void checkInvariants() const
Before unlocking, do DEV checkInvariants();.
SetState(StringData name, const std::set< HostAndPort > &seedNodes)
seedNodes must not be empty
Node * findOrCreateNode(const HostAndPort &host)
Returns the Node with the given host, or creates one if no Node has that host.
Node * findNode(const HostAndPort &host)
Returns the Node with the given host, or NULL if no Node has that host.
HostAndPort getMatchingHost(const ReadPreferenceSetting &criteria) const
Returns a host matching criteria or an empty host if no known host matches.