MongoDB  2.7.0
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 <deque>
25 #include <string>
26 #include <vector>
27 #include <set>
28 
29 #include "mongo/base/disallow_copying.h"
30 #include "mongo/client/dbclient_rs.h" // for TagSet and ReadPreferenceSettings
31 #include "mongo/client/replica_set_monitor.h"
32 #include "mongo/db/jsobj.h"
33 #include "mongo/platform/cstdint.h"
34 #include "mongo/platform/random.h"
35 #include "mongo/util/net/hostandport.h"
36 
37 namespace mongo {
39  IsMasterReply() : ok(false) {}
40  IsMasterReply(const HostAndPort& host, int64_t latencyMicros, const BSONObj& reply)
41  : ok(false)
42  , host(host)
43  , latencyMicros(latencyMicros) {
44  parse(reply);
45  }
46 
50  void parse(const BSONObj& obj);
51 
52  bool ok; // if false, ignore all other fields
53  BSONObj raw; // Always owned. Other fields are allowed to be a view into this.
54  std::string setName;
55  bool isMaster;
56  bool secondary;
57  bool hidden;
58  HostAndPort primary; // empty if not present
59  std::set<HostAndPort> normalHosts; // both "hosts" and "passives"
60  BSONObj tags;
61 
62  // remaining fields aren't in isMaster reply, but are known to caller.
63  HostAndPort host;
64  int64_t latencyMicros; // ignored if negative
65  };
66 
68  MONGO_DISALLOW_COPYING(SetState);
69  public:
70 
71  // A single node in the replicaSet
72  struct Node {
73  explicit Node(const HostAndPort& host)
74  : host(host)
75  , latencyMicros(unknownLatency) {
76  markFailed();
77  }
78 
79  void markFailed() {
80  isUp = false;
81  isMaster = false;
82  }
83 
84  bool matches(const ReadPreference& pref) const;
85 
99  bool matches(const BSONObj& tag) const;
100 
104  void update(const IsMasterReply& reply);
105 
106  // Intentionally chosen to compare worse than all known latencies.
107  static const int64_t unknownLatency; // = numeric_limits<int64_t>::max()
108 
109  HostAndPort host;
110  bool isUp;
111  bool isMaster; // implies isUp
112  int64_t latencyMicros; // unknownLatency if unknown
113  BSONObj tags; // owned
114  };
115  typedef std::vector<Node> Nodes;
116 
120  SetState(StringData name, const std::set<HostAndPort>& seedNodes);
121 
127  HostAndPort getMatchingHost(const ReadPreferenceSetting& criteria) const;
128 
132  Node* findNode(const HostAndPort& host);
133 
138  Node* findOrCreateNode(const HostAndPort& host);
139 
140  void updateNodeIfInNodes(const IsMasterReply& reply);
141 
142  std::string getServerAddress() const;
143 
147  void checkInvariants() const;
148 
149  static ConfigChangeHook configChangeHook;
150 
151  boost::mutex mutex; // must hold this to access any other member or method (except name).
152 
153  // If Refresher::getNextStep returns WAIT, you should wait on the condition_variable,
154  // releasing mutex. It will be notified when either getNextStep will return something other
155  // than WAIT, or a new host is available for consideration by getMatchingHost. Essentially,
156  // this will be hit whenever the _refreshUntilMatches loop has the potential to make
157  // progress.
158  // TODO consider splitting cv into two: one for when looking for a master, one for all other
159  // cases.
160  boost::condition_variable cv;
161 
162  const std::string name; // safe to read outside lock since it is const
163  int consecutiveFailedScans;
164  std::set<HostAndPort> seedNodes; // updated whenever a master reports set membership changes
165  HostAndPort lastSeenMaster; // empty if we have never seen a master. can be same as current
166  Nodes nodes; // maintained sorted and unique by host
167  ScanStatePtr currentScan; // NULL if no scan in progress
168  int64_t latencyThresholdMicros;
169  mutable PseudoRandom rand; // only used for host selection to balance load
170  mutable int roundRobin; // used when useDeterministicHostSelection is true
171  };
172 
174  MONGO_DISALLOW_COPYING(ScanState);
175  public:
176  ScanState() : foundUpMaster(false), foundAnyUpNodes(false) {}
177 
182  template <typename Container>
183  void enqueAllUntriedHosts(const Container& container, PseudoRandom& rand);
184 
185  // Access to fields is guarded by associated SetState's mutex.
186  bool foundUpMaster;
187  bool foundAnyUpNodes;
188  std::deque<HostAndPort> hostsToScan; // Work queue.
189  std::set<HostAndPort> possibleNodes; // Nodes reported by non-primary hosts.
190  std::set<HostAndPort> waitingFor; // Hosts we have dispatched but haven't replied yet.
191  std::set<HostAndPort> triedHosts; // Hosts that have been returned from getNextStep.
192 
193  // All responses go here until we find a master.
194  typedef std::vector<IsMasterReply> UnconfirmedReplies;
195  UnconfirmedReplies unconfirmedReplies;
196  };
197 }
Node * findOrCreateNode(const HostAndPort &host)
Returns the Node with the given host, or creates one if no Node has that host.
Definition: replica_set_monitor.cpp:971
BSON classes.
HostAndPort getMatchingHost(const ReadPreferenceSetting &criteria) const
Returns a host matching criteria or an empty host if no known host matches.
Definition: replica_set_monitor.cpp:881
Definition: dbclient_rs.h:290
void enqueAllUntriedHosts(const Container &container, PseudoRandom &rand)
Adds all hosts in container that aren't in triedHosts to hostsToScan, then shuffles the queue...
Connect to a Replica Set, from C++.
void update(const IsMasterReply &reply)
Updates this Node based on information in reply.
Definition: replica_set_monitor.cpp:827
Definition: replica_set_monitor_internal.h:38
On pthread systems, it is an error to destroy a mutex while held (boost mutex may use pthread)...
Definition: mutex.h:74
helper for manipulating host:port connection endpoints.
Definition: hostandport.h:31
Definition: replica_set_monitor_internal.h:67
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
void parse(const BSONObj &obj)
Never throws.
Definition: replica_set_monitor.cpp:766
SetState(StringData name, const std::set< HostAndPort > &seedNodes)
seedNodes must not be empty
Definition: replica_set_monitor.cpp:855
void checkInvariants() const
Before unlocking, do DEV checkInvariants();.
Definition: replica_set_monitor.cpp:1009
Node * findNode(const HostAndPort &host)
Returns the Node with the given host, or NULL if no Node has that host.
Definition: replica_set_monitor.cpp:963
Definition: replica_set_monitor_internal.h:72
Definition: replica_set_monitor_internal.h:173