summaryrefslogtreecommitdiff
path: root/src/mongo/client/dbclient_rs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client/dbclient_rs.h')
-rw-r--r--src/mongo/client/dbclient_rs.h568
1 files changed, 297 insertions, 271 deletions
diff --git a/src/mongo/client/dbclient_rs.h b/src/mongo/client/dbclient_rs.h
index fb29559c80a..3e5a9f07dd2 100644
--- a/src/mongo/client/dbclient_rs.h
+++ b/src/mongo/client/dbclient_rs.h
@@ -36,277 +36,303 @@
namespace mongo {
- class ReplicaSetMonitor;
- class TagSet;
- struct ReadPreferenceSetting;
- typedef std::shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr;
-
- /** Use this class to connect to a replica set of servers. The class will manage
- checking for which server in a replica set is master, and do failover automatically.
-
- This can also be used to connect to replica pairs since pairs are a subset of sets
-
- On a failover situation, expect at least one operation to return an error (throw
- an exception) before the failover is complete. Operations are not retried.
+class ReplicaSetMonitor;
+class TagSet;
+struct ReadPreferenceSetting;
+typedef std::shared_ptr<ReplicaSetMonitor> ReplicaSetMonitorPtr;
+
+/** Use this class to connect to a replica set of servers. The class will manage
+ checking for which server in a replica set is master, and do failover automatically.
+
+ This can also be used to connect to replica pairs since pairs are a subset of sets
+
+ On a failover situation, expect at least one operation to return an error (throw
+ an exception) before the failover is complete. Operations are not retried.
+*/
+class DBClientReplicaSet : public DBClientBase {
+public:
+ using DBClientBase::query;
+ using DBClientBase::update;
+ using DBClientBase::remove;
+
+ /** Call connect() after constructing. autoReconnect is always on for DBClientReplicaSet connections. */
+ DBClientReplicaSet(const std::string& name,
+ const std::vector<HostAndPort>& servers,
+ double so_timeout = 0);
+ virtual ~DBClientReplicaSet();
+
+ /**
+ * Returns false if no member of the set were reachable. This object
+ * can still be used even when false was returned as it will try to
+ * reconnect when you use it later.
+ */
+ bool connect();
+
+ /**
+ * Logs out the connection for the given database.
+ *
+ * @param dbname the database to logout from.
+ * @param info the result object for the logout command (provided for backwards
+ * compatibility with mongo shell)
+ */
+ virtual void logout(const std::string& dbname, BSONObj& info);
+
+ // ----------- simple functions --------------
+
+ /** throws userassertion "no master found" */
+ virtual std::unique_ptr<DBClientCursor> query(const std::string& ns,
+ Query query,
+ int nToReturn = 0,
+ int nToSkip = 0,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0,
+ int batchSize = 0);
+
+ /** throws userassertion "no master found" */
+ virtual BSONObj findOne(const std::string& ns,
+ const Query& query,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0);
+
+ virtual void insert(const std::string& ns, BSONObj obj, int flags = 0);
+
+ /** insert multiple objects. Note that single object insert is asynchronous, so this version
+ is only nominally faster and not worth a special effort to try to use. */
+ virtual void insert(const std::string& ns, const std::vector<BSONObj>& v, int flags = 0);
+
+ virtual void remove(const std::string& ns, Query obj, int flags);
+
+ virtual void update(const std::string& ns, Query query, BSONObj obj, int flags);
+
+ virtual void killCursor(long long cursorID);
+
+ // ---- access raw connections ----
+
+ /**
+ * WARNING: this method is very dangerous - this object can decide to free the
+ * returned master connection any time.
+ *
+ * @return the reference to the address that points to the master connection.
+ */
+ DBClientConnection& masterConn();
+
+ /**
+ * WARNING: this method is very dangerous - this object can decide to free the
+ * returned master connection any time. This can also unpin the cached
+ * slaveOk/read preference connection.
+ *
+ * @return the reference to the address that points to a secondary connection.
+ */
+ DBClientConnection& slaveConn();
+
+ // ---- callback pieces -------
+
+ virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0);
+ virtual bool recv(Message& toRecv);
+ virtual void checkResponse(const char* data,
+ int nReturned,
+ bool* retry = NULL,
+ std::string* targetHost = NULL);
+
+ /* this is the callback from our underlying connections to notify us that we got a "not master" error.
+ */
+ void isntMaster();
+
+ /* this is used to indicate we got a "not master or secondary" error from a secondary.
+ */
+ void isntSecondary();
+
+ // ----- status ------
+
+ virtual bool isFailed() const {
+ return !_master || _master->isFailed();
+ }
+ bool isStillConnected();
+
+ // ----- informational ----
+
+ /**
+ * Gets the replica set name of the set we are connected to.
+ */
+ const std::string& getSetName() const {
+ return _setName;
+ }
+
+ /**
+ * Returns the HostAndPort of the server this connection believes belongs to the primary,
+ * or returns an empty HostAndPort if it doesn't know about a current primary.
+ */
+ HostAndPort getSuspectedPrimaryHostAndPort() const;
+
+ double getSoTimeout() const {
+ return _so_timeout;
+ }
+
+ std::string toString() const {
+ return getServerAddress();
+ }
+
+ std::string getServerAddress() const;
+
+ virtual ConnectionString::ConnectionType type() const {
+ return ConnectionString::SET;
+ }
+ virtual bool lazySupported() const {
+ return true;
+ }
+
+ rpc::UniqueReply runCommandWithMetadata(StringData database,
+ StringData command,
+ const BSONObj& metadata,
+ const BSONObj& commandArgs) final;
+
+ void setRequestMetadataWriter(rpc::RequestMetadataWriter writer) final;
+
+ void setReplyMetadataReader(rpc::ReplyMetadataReader reader) final;
+ // ---- low level ------
+
+ virtual bool call(Message& toSend,
+ Message& response,
+ bool assertOk = true,
+ std::string* actualServer = 0);
+ virtual bool callRead(Message& toSend, Message& response) {
+ return checkMaster()->callRead(toSend, response);
+ }
+
+ /**
+ * Returns whether a query or command can be sent to secondaries based on the query object
+ * and options.
+ *
+ * @param ns the namespace of the query.
+ * @param queryObj the query object to check.
+ * @param queryOptions the query options
+ *
+ * @return true if the query/cmd could potentially be sent to a secondary, false otherwise
+ */
+ static bool isSecondaryQuery(const std::string& ns, const BSONObj& queryObj, int queryOptions);
+
+ /**
+ * Performs a "soft reset" by clearing all states relating to secondary nodes and
+ * returning secondary connections to the pool.
+ */
+ virtual void reset();
+
+ /**
+ * @bool setting if true, DBClientReplicaSet connections will make sure that secondary
+ * connections are authenticated and log them before returning them to the pool.
+ */
+ static void setAuthPooledSecondaryConn(bool setting);
+
+protected:
+ /** Authorize. Authorizes all nodes as needed
*/
- class DBClientReplicaSet : public DBClientBase {
+ virtual void _auth(const BSONObj& params);
+
+ virtual void sayPiggyBack(Message& toSend) {
+ checkMaster()->say(toSend);
+ }
+
+private:
+ /**
+ * Used to simplify slave-handling logic on errors
+ *
+ * @return back the passed cursor
+ * @throws DBException if the directed node cannot accept the query because it
+ * is not a master
+ */
+ std::unique_ptr<DBClientCursor> checkSlaveQueryResult(std::unique_ptr<DBClientCursor> result);
+
+ DBClientConnection* checkMaster();
+
+ /**
+ * Helper method for selecting a node based on the read preference. Will advance
+ * the tag tags object if it cannot find a node that matches the current tag.
+ *
+ * @param readPref the preference to use for selecting a node.
+ *
+ * @return a pointer to the new connection object if it can find a good connection.
+ * Otherwise it returns NULL.
+ *
+ * @throws DBException when an error occurred either when trying to connect to
+ * a node that was thought to be ok or when an assertion happened.
+ */
+ DBClientConnection* selectNodeUsingTags(std::shared_ptr<ReadPreferenceSetting> readPref);
+
+ /**
+ * @return true if the last host used in the last slaveOk query is still in the
+ * set and can be used for the given read preference.
+ */
+ bool checkLastHost(const ReadPreferenceSetting* readPref);
+
+ /**
+ * Destroys all cached information about the last slaveOk operation.
+ */
+ void invalidateLastSlaveOkCache();
+
+ void _auth(DBClientConnection* conn);
+
+ /**
+ * Calls logout on the connection for all known database this DBClientRS instance has
+ * logged in.
+ */
+ void logoutAll(DBClientConnection* conn);
+
+ /**
+ * Clears the master connection.
+ */
+ void resetMaster();
+
+ /**
+ * Clears the slaveOk connection and returns it to the pool if not the same as _master.
+ */
+ void resetSlaveOkConn();
+
+ /**
+ * Maximum number of retries to make for auto-retry logic when performing a slave ok
+ * operation.
+ */
+ static const size_t MAX_RETRY;
+
+ // TODO: remove this when processes other than mongos uses the driver version.
+ static bool _authPooledSecondaryConn;
+
+ // Throws a DBException if the monitor doesn't exist and there isn't a cached seed to use.
+ ReplicaSetMonitorPtr _getMonitor() const;
+
+ std::string _setName;
+
+ HostAndPort _masterHost;
+ std::unique_ptr<DBClientConnection> _master;
+
+ // Last used host in a slaveOk query (can be a primary).
+ HostAndPort _lastSlaveOkHost;
+ // Last used connection in a slaveOk query (can be a primary).
+ // Connection can either be owned here or returned to the connection pool. Note that
+ // if connection is primary, it is owned by _master so it is incorrect to return
+ // it to the pool.
+ std::unique_ptr<DBClientConnection> _lastSlaveOkConn;
+ std::shared_ptr<ReadPreferenceSetting> _lastReadPref;
+
+ double _so_timeout;
+
+ // we need to store so that when we connect to a new node on failure
+ // we can re-auth
+ // this could be a security issue, as the password is stored in memory
+ // not sure if/how we should handle
+ std::map<std::string, BSONObj> _auths; // dbName -> auth parameters
+
+protected:
+ /**
+ * for storing (non-threadsafe) information between lazy calls
+ */
+ class LazyState {
public:
- using DBClientBase::query;
- using DBClientBase::update;
- using DBClientBase::remove;
-
- /** Call connect() after constructing. autoReconnect is always on for DBClientReplicaSet connections. */
- DBClientReplicaSet( const std::string& name , const std::vector<HostAndPort>& servers, double so_timeout=0 );
- virtual ~DBClientReplicaSet();
-
- /**
- * Returns false if no member of the set were reachable. This object
- * can still be used even when false was returned as it will try to
- * reconnect when you use it later.
- */
- bool connect();
-
- /**
- * Logs out the connection for the given database.
- *
- * @param dbname the database to logout from.
- * @param info the result object for the logout command (provided for backwards
- * compatibility with mongo shell)
- */
- virtual void logout(const std::string& dbname, BSONObj& info);
-
- // ----------- simple functions --------------
-
- /** throws userassertion "no master found" */
- virtual std::unique_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
- const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
-
- /** throws userassertion "no master found" */
- virtual BSONObj findOne(const std::string &ns, const Query& query, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
-
- virtual void insert( const std::string &ns , BSONObj obj , int flags=0);
-
- /** insert multiple objects. Note that single object insert is asynchronous, so this version
- is only nominally faster and not worth a special effort to try to use. */
- virtual void insert( const std::string &ns, const std::vector< BSONObj >& v , int flags=0);
-
- virtual void remove( const std::string &ns , Query obj , int flags );
-
- virtual void update( const std::string &ns , Query query , BSONObj obj , int flags );
-
- virtual void killCursor( long long cursorID );
-
- // ---- access raw connections ----
-
- /**
- * WARNING: this method is very dangerous - this object can decide to free the
- * returned master connection any time.
- *
- * @return the reference to the address that points to the master connection.
- */
- DBClientConnection& masterConn();
-
- /**
- * WARNING: this method is very dangerous - this object can decide to free the
- * returned master connection any time. This can also unpin the cached
- * slaveOk/read preference connection.
- *
- * @return the reference to the address that points to a secondary connection.
- */
- DBClientConnection& slaveConn();
-
- // ---- callback pieces -------
-
- virtual void say( Message &toSend, bool isRetry = false , std::string* actualServer = 0);
- virtual bool recv( Message &toRecv );
- virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, std::string* targetHost = NULL );
-
- /* this is the callback from our underlying connections to notify us that we got a "not master" error.
- */
- void isntMaster();
-
- /* this is used to indicate we got a "not master or secondary" error from a secondary.
- */
- void isntSecondary();
-
- // ----- status ------
-
- virtual bool isFailed() const { return ! _master || _master->isFailed(); }
- bool isStillConnected();
-
- // ----- informational ----
-
- /**
- * Gets the replica set name of the set we are connected to.
- */
- const std::string& getSetName() const { return _setName; }
-
- /**
- * Returns the HostAndPort of the server this connection believes belongs to the primary,
- * or returns an empty HostAndPort if it doesn't know about a current primary.
- */
- HostAndPort getSuspectedPrimaryHostAndPort() const;
-
- double getSoTimeout() const { return _so_timeout; }
-
- std::string toString() const { return getServerAddress(); }
-
- std::string getServerAddress() const;
-
- virtual ConnectionString::ConnectionType type() const { return ConnectionString::SET; }
- virtual bool lazySupported() const { return true; }
-
- rpc::UniqueReply runCommandWithMetadata(StringData database,
- StringData command,
- const BSONObj& metadata,
- const BSONObj& commandArgs) final;
-
- void setRequestMetadataWriter(rpc::RequestMetadataWriter writer) final;
-
- void setReplyMetadataReader(rpc::ReplyMetadataReader reader) final;
- // ---- low level ------
-
- virtual bool call( Message &toSend, Message &response, bool assertOk=true , std::string * actualServer = 0 );
- virtual bool callRead( Message& toSend , Message& response ) { return checkMaster()->callRead( toSend , response ); }
-
- /**
- * Returns whether a query or command can be sent to secondaries based on the query object
- * and options.
- *
- * @param ns the namespace of the query.
- * @param queryObj the query object to check.
- * @param queryOptions the query options
- *
- * @return true if the query/cmd could potentially be sent to a secondary, false otherwise
- */
- static bool isSecondaryQuery( const std::string& ns,
- const BSONObj& queryObj,
- int queryOptions );
-
- /**
- * Performs a "soft reset" by clearing all states relating to secondary nodes and
- * returning secondary connections to the pool.
- */
- virtual void reset();
-
- /**
- * @bool setting if true, DBClientReplicaSet connections will make sure that secondary
- * connections are authenticated and log them before returning them to the pool.
- */
- static void setAuthPooledSecondaryConn(bool setting);
-
- protected:
- /** Authorize. Authorizes all nodes as needed
- */
- virtual void _auth(const BSONObj& params);
-
- virtual void sayPiggyBack( Message &toSend ) { checkMaster()->say( toSend ); }
-
- private:
- /**
- * Used to simplify slave-handling logic on errors
- *
- * @return back the passed cursor
- * @throws DBException if the directed node cannot accept the query because it
- * is not a master
- */
- std::unique_ptr<DBClientCursor> checkSlaveQueryResult( std::unique_ptr<DBClientCursor> result );
-
- DBClientConnection * checkMaster();
-
- /**
- * Helper method for selecting a node based on the read preference. Will advance
- * the tag tags object if it cannot find a node that matches the current tag.
- *
- * @param readPref the preference to use for selecting a node.
- *
- * @return a pointer to the new connection object if it can find a good connection.
- * Otherwise it returns NULL.
- *
- * @throws DBException when an error occurred either when trying to connect to
- * a node that was thought to be ok or when an assertion happened.
- */
- DBClientConnection* selectNodeUsingTags(std::shared_ptr<ReadPreferenceSetting> readPref);
-
- /**
- * @return true if the last host used in the last slaveOk query is still in the
- * set and can be used for the given read preference.
- */
- bool checkLastHost(const ReadPreferenceSetting* readPref);
-
- /**
- * Destroys all cached information about the last slaveOk operation.
- */
- void invalidateLastSlaveOkCache();
-
- void _auth( DBClientConnection * conn );
-
- /**
- * Calls logout on the connection for all known database this DBClientRS instance has
- * logged in.
- */
- void logoutAll(DBClientConnection* conn);
-
- /**
- * Clears the master connection.
- */
- void resetMaster();
-
- /**
- * Clears the slaveOk connection and returns it to the pool if not the same as _master.
- */
- void resetSlaveOkConn();
-
- /**
- * Maximum number of retries to make for auto-retry logic when performing a slave ok
- * operation.
- */
- static const size_t MAX_RETRY;
-
- // TODO: remove this when processes other than mongos uses the driver version.
- static bool _authPooledSecondaryConn;
-
- // Throws a DBException if the monitor doesn't exist and there isn't a cached seed to use.
- ReplicaSetMonitorPtr _getMonitor() const;
-
- std::string _setName;
-
- HostAndPort _masterHost;
- std::unique_ptr<DBClientConnection> _master;
-
- // Last used host in a slaveOk query (can be a primary).
- HostAndPort _lastSlaveOkHost;
- // Last used connection in a slaveOk query (can be a primary).
- // Connection can either be owned here or returned to the connection pool. Note that
- // if connection is primary, it is owned by _master so it is incorrect to return
- // it to the pool.
- std::unique_ptr<DBClientConnection> _lastSlaveOkConn;
- std::shared_ptr<ReadPreferenceSetting> _lastReadPref;
-
- double _so_timeout;
-
- // we need to store so that when we connect to a new node on failure
- // we can re-auth
- // this could be a security issue, as the password is stored in memory
- // not sure if/how we should handle
- std::map<std::string, BSONObj> _auths; // dbName -> auth parameters
-
- protected:
-
- /**
- * for storing (non-threadsafe) information between lazy calls
- */
- class LazyState {
- public:
- LazyState() :
- _lastClient( NULL ), _lastOp( -1 ), _secondaryQueryOk( false ), _retries( 0 ) {}
- DBClientConnection* _lastClient;
- int _lastOp;
- bool _secondaryQueryOk;
- int _retries;
-
- } _lazyState;
-
- };
-
+ LazyState() : _lastClient(NULL), _lastOp(-1), _secondaryQueryOk(false), _retries(0) {}
+ DBClientConnection* _lastClient;
+ int _lastOp;
+ bool _secondaryQueryOk;
+ int _retries;
+
+ } _lazyState;
+};
}