summaryrefslogtreecommitdiff
path: root/src/mongo/client/connpool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client/connpool.h')
-rw-r--r--src/mongo/client/connpool.h525
1 files changed, 275 insertions, 250 deletions
diff --git a/src/mongo/client/connpool.h b/src/mongo/client/connpool.h
index 0324a5be080..04beed0d33d 100644
--- a/src/mongo/client/connpool.h
+++ b/src/mongo/client/connpool.h
@@ -39,324 +39,349 @@
namespace mongo {
- class DBConnectionPool;
+class DBConnectionPool;
+
+/**
+ * not thread safe
+ * thread safety is handled by DBConnectionPool
+ */
+class PoolForHost {
+public:
+ // Sentinel value indicating pool has no cleanup limit
+ static const int kPoolSizeUnlimited;
+
+ PoolForHost()
+ : _created(0),
+ _minValidCreationTimeMicroSec(0),
+ _type(ConnectionString::INVALID),
+ _maxPoolSize(kPoolSizeUnlimited) {}
+
+ PoolForHost(const PoolForHost& other)
+ : _created(other._created),
+ _minValidCreationTimeMicroSec(other._minValidCreationTimeMicroSec),
+ _type(other._type),
+ _maxPoolSize(other._maxPoolSize) {
+ verify(_created == 0);
+ verify(other._pool.size() == 0);
+ }
+
+ ~PoolForHost();
/**
- * not thread safe
- * thread safety is handled by DBConnectionPool
+ * Returns the maximum number of connections stored in the pool
*/
- class PoolForHost {
- public:
-
- // Sentinel value indicating pool has no cleanup limit
- static const int kPoolSizeUnlimited;
-
- PoolForHost() :
- _created(0),
- _minValidCreationTimeMicroSec(0),
- _type(ConnectionString::INVALID),
- _maxPoolSize(kPoolSizeUnlimited) {
- }
-
- PoolForHost(const PoolForHost& other) :
- _created(other._created),
- _minValidCreationTimeMicroSec(other._minValidCreationTimeMicroSec),
- _type(other._type),
- _maxPoolSize(other._maxPoolSize) {
- verify(_created == 0);
- verify(other._pool.size() == 0);
- }
-
- ~PoolForHost();
-
- /**
- * Returns the maximum number of connections stored in the pool
- */
- int getMaxPoolSize() { return _maxPoolSize; }
-
- /**
- * Sets the maximum number of connections stored in the pool
- */
- void setMaxPoolSize( int maxPoolSize ) { _maxPoolSize = maxPoolSize; }
-
- int numAvailable() const { return (int)_pool.size(); }
-
- void createdOne( DBClientBase * base );
- long long numCreated() const { return _created; }
-
- ConnectionString::ConnectionType type() const { verify(_created); return _type; }
-
- /**
- * gets a connection or return NULL
- */
- DBClientBase * get( DBConnectionPool * pool , double socketTimeout );
+ int getMaxPoolSize() {
+ return _maxPoolSize;
+ }
- // Deletes all connections in the pool
- void clear();
+ /**
+ * Sets the maximum number of connections stored in the pool
+ */
+ void setMaxPoolSize(int maxPoolSize) {
+ _maxPoolSize = maxPoolSize;
+ }
- void done( DBConnectionPool * pool , DBClientBase * c );
+ int numAvailable() const {
+ return (int)_pool.size();
+ }
- void flush();
+ void createdOne(DBClientBase* base);
+ long long numCreated() const {
+ return _created;
+ }
- void getStaleConnections( std::vector<DBClientBase*>& stale );
+ ConnectionString::ConnectionType type() const {
+ verify(_created);
+ return _type;
+ }
- /**
- * Sets the lower bound for creation times that can be considered as
- * good connections.
- */
- void reportBadConnectionAt(uint64_t microSec);
+ /**
+ * gets a connection or return NULL
+ */
+ DBClientBase* get(DBConnectionPool* pool, double socketTimeout);
- /**
- * @return true if the given creation time is considered to be not
- * good for use.
- */
- bool isBadSocketCreationTime(uint64_t microSec);
+ // Deletes all connections in the pool
+ void clear();
- /**
- * Sets the host name to a new one, only if it is currently empty.
- */
- void initializeHostName(const std::string& hostName);
+ void done(DBConnectionPool* pool, DBClientBase* c);
- private:
+ void flush();
- struct StoredConnection {
- StoredConnection( DBClientBase * c );
+ void getStaleConnections(std::vector<DBClientBase*>& stale);
- bool ok( time_t now );
+ /**
+ * Sets the lower bound for creation times that can be considered as
+ * good connections.
+ */
+ void reportBadConnectionAt(uint64_t microSec);
- DBClientBase* conn;
- time_t when;
- };
+ /**
+ * @return true if the given creation time is considered to be not
+ * good for use.
+ */
+ bool isBadSocketCreationTime(uint64_t microSec);
- std::string _hostName;
- std::stack<StoredConnection> _pool;
+ /**
+ * Sets the host name to a new one, only if it is currently empty.
+ */
+ void initializeHostName(const std::string& hostName);
- int64_t _created;
- uint64_t _minValidCreationTimeMicroSec;
- ConnectionString::ConnectionType _type;
+private:
+ struct StoredConnection {
+ StoredConnection(DBClientBase* c);
- // The maximum number of connections we'll save in the pool
- int _maxPoolSize;
- };
+ bool ok(time_t now);
- class DBConnectionHook {
- public:
- virtual ~DBConnectionHook() {}
- virtual void onCreate( DBClientBase * conn ) {}
- virtual void onHandedOut( DBClientBase * conn ) {}
- virtual void onRelease(DBClientBase* conn) {}
- virtual void onDestroy( DBClientBase * conn ) {}
+ DBClientBase* conn;
+ time_t when;
};
- /** Database connection pool.
+ std::string _hostName;
+ std::stack<StoredConnection> _pool;
- Generally, use ScopedDbConnection and do not call these directly.
+ int64_t _created;
+ uint64_t _minValidCreationTimeMicroSec;
+ ConnectionString::ConnectionType _type;
- This class, so far, is suitable for use with unauthenticated connections.
- Support for authenticated connections requires some adjustments: please
- request...
+ // The maximum number of connections we'll save in the pool
+ int _maxPoolSize;
+};
- Usage:
+class DBConnectionHook {
+public:
+ virtual ~DBConnectionHook() {}
+ virtual void onCreate(DBClientBase* conn) {}
+ virtual void onHandedOut(DBClientBase* conn) {}
+ virtual void onRelease(DBClientBase* conn) {}
+ virtual void onDestroy(DBClientBase* conn) {}
+};
- {
- ScopedDbConnection c("myserver");
- c.conn()...
- }
- */
- class DBConnectionPool : public PeriodicTask {
- public:
+/** Database connection pool.
- DBConnectionPool();
- ~DBConnectionPool();
+ Generally, use ScopedDbConnection and do not call these directly.
- /** right now just controls some asserts. defaults to "dbconnectionpool" */
- void setName( const std::string& name ) { _name = name; }
+ This class, so far, is suitable for use with unauthenticated connections.
+ Support for authenticated connections requires some adjustments: please
+ request...
- /**
- * Returns the maximum number of connections pooled per-host
- *
- * This setting only applies to new host connection pools, previously-pooled host pools are
- * unaffected.
- */
- int getMaxPoolSize() { return _maxPoolSize; }
+ Usage:
- /**
- * Sets the maximum number of connections pooled per-host.
- *
- * This setting only applies to new host connection pools, previously-pooled host pools are
- * unaffected.
- */
- void setMaxPoolSize( int maxPoolSize ) { _maxPoolSize = maxPoolSize; }
+ {
+ ScopedDbConnection c("myserver");
+ c.conn()...
+ }
+*/
+class DBConnectionPool : public PeriodicTask {
+public:
+ DBConnectionPool();
+ ~DBConnectionPool();
- void onCreate( DBClientBase * conn );
- void onHandedOut( DBClientBase * conn );
- void onDestroy( DBClientBase * conn );
- void onRelease(DBClientBase* conn);
+ /** right now just controls some asserts. defaults to "dbconnectionpool" */
+ void setName(const std::string& name) {
+ _name = name;
+ }
- void flush();
+ /**
+ * Returns the maximum number of connections pooled per-host
+ *
+ * This setting only applies to new host connection pools, previously-pooled host pools are
+ * unaffected.
+ */
+ int getMaxPoolSize() {
+ return _maxPoolSize;
+ }
- DBClientBase *get(const std::string& host, double socketTimeout = 0);
- DBClientBase *get(const ConnectionString& host, double socketTimeout = 0);
+ /**
+ * Sets the maximum number of connections pooled per-host.
+ *
+ * This setting only applies to new host connection pools, previously-pooled host pools are
+ * unaffected.
+ */
+ void setMaxPoolSize(int maxPoolSize) {
+ _maxPoolSize = maxPoolSize;
+ }
- void release(const std::string& host, DBClientBase *c);
+ void onCreate(DBClientBase* conn);
+ void onHandedOut(DBClientBase* conn);
+ void onDestroy(DBClientBase* conn);
+ void onRelease(DBClientBase* conn);
- void addHook( DBConnectionHook * hook ); // we take ownership
- void appendInfo( BSONObjBuilder& b );
+ void flush();
- /**
- * Clears all connections for all host.
- */
- void clear();
+ DBClientBase* get(const std::string& host, double socketTimeout = 0);
+ DBClientBase* get(const ConnectionString& host, double socketTimeout = 0);
- /**
- * Checks whether the connection for a given host is black listed or not.
- *
- * @param hostName the name of the host the connection connects to.
- * @param conn the connection to check.
- *
- * @return true if the connection is not bad, meaning, it is good to keep it for
- * future use.
- */
- bool isConnectionGood(const std::string& host, DBClientBase* conn);
+ void release(const std::string& host, DBClientBase* c);
- // Removes and deletes all connections from the pool for the host (regardless of timeout)
- void removeHost( const std::string& host );
+ void addHook(DBConnectionHook* hook); // we take ownership
+ void appendInfo(BSONObjBuilder& b);
- /** compares server namees, but is smart about replica set names */
- struct serverNameCompare {
- bool operator()( const std::string& a , const std::string& b ) const;
- };
+ /**
+ * Clears all connections for all host.
+ */
+ void clear();
- virtual std::string taskName() const { return "DBConnectionPool-cleaner"; }
- virtual void taskDoWork();
+ /**
+ * Checks whether the connection for a given host is black listed or not.
+ *
+ * @param hostName the name of the host the connection connects to.
+ * @param conn the connection to check.
+ *
+ * @return true if the connection is not bad, meaning, it is good to keep it for
+ * future use.
+ */
+ bool isConnectionGood(const std::string& host, DBClientBase* conn);
- private:
- DBConnectionPool( DBConnectionPool& p );
+ // Removes and deletes all connections from the pool for the host (regardless of timeout)
+ void removeHost(const std::string& host);
- DBClientBase* _get( const std::string& ident , double socketTimeout );
+ /** compares server namees, but is smart about replica set names */
+ struct serverNameCompare {
+ bool operator()(const std::string& a, const std::string& b) const;
+ };
- DBClientBase* _finishCreate( const std::string& ident , double socketTimeout, DBClientBase* conn );
+ virtual std::string taskName() const {
+ return "DBConnectionPool-cleaner";
+ }
+ virtual void taskDoWork();
- struct PoolKey {
- PoolKey( const std::string& i , double t ) : ident( i ) , timeout( t ) {}
- std::string ident;
- double timeout;
- };
+private:
+ DBConnectionPool(DBConnectionPool& p);
- struct poolKeyCompare {
- bool operator()( const PoolKey& a , const PoolKey& b ) const;
- };
+ DBClientBase* _get(const std::string& ident, double socketTimeout);
- typedef std::map<PoolKey,PoolForHost,poolKeyCompare> PoolMap; // servername -> pool
+ DBClientBase* _finishCreate(const std::string& ident, double socketTimeout, DBClientBase* conn);
- stdx::mutex _mutex;
- std::string _name;
+ struct PoolKey {
+ PoolKey(const std::string& i, double t) : ident(i), timeout(t) {}
+ std::string ident;
+ double timeout;
+ };
- // The maximum number of connections we'll save in the pool per-host
- // PoolForHost::kPoolSizeUnlimited is a sentinel value meaning "no limit"
- // 0 effectively disables the pool
- int _maxPoolSize;
+ struct poolKeyCompare {
+ bool operator()(const PoolKey& a, const PoolKey& b) const;
+ };
- PoolMap _pools;
+ typedef std::map<PoolKey, PoolForHost, poolKeyCompare> PoolMap; // servername -> pool
- // pointers owned by me, right now they leak on shutdown
- // _hooks itself also leaks because it creates a shutdown race condition
- std::list<DBConnectionHook*> * _hooks;
+ stdx::mutex _mutex;
+ std::string _name;
- };
+ // The maximum number of connections we'll save in the pool per-host
+ // PoolForHost::kPoolSizeUnlimited is a sentinel value meaning "no limit"
+ // 0 effectively disables the pool
+ int _maxPoolSize;
- class AScopedConnection {
- MONGO_DISALLOW_COPYING(AScopedConnection);
- public:
- AScopedConnection() { _numConnections.fetchAndAdd(1); }
- virtual ~AScopedConnection() { _numConnections.fetchAndAdd(-1); }
+ PoolMap _pools;
- virtual DBClientBase* get() = 0;
- virtual void done() = 0;
- virtual std::string getHost() const = 0;
+ // pointers owned by me, right now they leak on shutdown
+ // _hooks itself also leaks because it creates a shutdown race condition
+ std::list<DBConnectionHook*>* _hooks;
+};
- /**
- * @return true iff this has a connection to the db
- */
- virtual bool ok() const = 0;
+class AScopedConnection {
+ MONGO_DISALLOW_COPYING(AScopedConnection);
- /**
- * @return total number of current instances of AScopedConnection
- */
- static int getNumConnections() { return _numConnections.load(); }
+public:
+ AScopedConnection() {
+ _numConnections.fetchAndAdd(1);
+ }
+ virtual ~AScopedConnection() {
+ _numConnections.fetchAndAdd(-1);
+ }
- private:
- static AtomicInt32 _numConnections;
- };
+ virtual DBClientBase* get() = 0;
+ virtual void done() = 0;
+ virtual std::string getHost() const = 0;
- /** Use to get a connection from the pool. On exceptions things
- clean up nicely (i.e. the socket gets closed automatically when the
- scopeddbconnection goes out of scope).
- */
- class ScopedDbConnection : public AScopedConnection {
- public:
- /** the main constructor you want to use
- throws UserException if can't connect
- */
- explicit ScopedDbConnection(const std::string& host, double socketTimeout = 0);
- explicit ScopedDbConnection(const ConnectionString& host, double socketTimeout = 0);
+ /**
+ * @return true iff this has a connection to the db
+ */
+ virtual bool ok() const = 0;
- ScopedDbConnection() : _host( "" ) , _conn(0), _socketTimeout( 0 ) {}
+ /**
+ * @return total number of current instances of AScopedConnection
+ */
+ static int getNumConnections() {
+ return _numConnections.load();
+ }
+
+private:
+ static AtomicInt32 _numConnections;
+};
+
+/** Use to get a connection from the pool. On exceptions things
+ clean up nicely (i.e. the socket gets closed automatically when the
+ scopeddbconnection goes out of scope).
+*/
+class ScopedDbConnection : public AScopedConnection {
+public:
+ /** the main constructor you want to use
+ throws UserException if can't connect
+ */
+ explicit ScopedDbConnection(const std::string& host, double socketTimeout = 0);
+ explicit ScopedDbConnection(const ConnectionString& host, double socketTimeout = 0);
- /* @param conn - bind to an existing connection */
- ScopedDbConnection(const std::string& host, DBClientBase* conn, double socketTimeout = 0 ) : _host( host ) , _conn( conn ), _socketTimeout( socketTimeout ) {
- _setSocketTimeout();
- }
+ ScopedDbConnection() : _host(""), _conn(0), _socketTimeout(0) {}
- ~ScopedDbConnection();
+ /* @param conn - bind to an existing connection */
+ ScopedDbConnection(const std::string& host, DBClientBase* conn, double socketTimeout = 0)
+ : _host(host), _conn(conn), _socketTimeout(socketTimeout) {
+ _setSocketTimeout();
+ }
- static void clearPool();
+ ~ScopedDbConnection();
- /** get the associated connection object */
- DBClientBase* operator->() {
- uassert( 11004 , "connection was returned to the pool already" , _conn );
- return _conn;
- }
+ static void clearPool();
- /** get the associated connection object */
- DBClientBase& conn() {
- uassert( 11005 , "connection was returned to the pool already" , _conn );
- return *_conn;
- }
+ /** get the associated connection object */
+ DBClientBase* operator->() {
+ uassert(11004, "connection was returned to the pool already", _conn);
+ return _conn;
+ }
- /** get the associated connection object */
- DBClientBase* get() {
- uassert( 13102 , "connection was returned to the pool already" , _conn );
- return _conn;
- }
+ /** get the associated connection object */
+ DBClientBase& conn() {
+ uassert(11005, "connection was returned to the pool already", _conn);
+ return *_conn;
+ }
- bool ok() const { return _conn != NULL; }
+ /** get the associated connection object */
+ DBClientBase* get() {
+ uassert(13102, "connection was returned to the pool already", _conn);
+ return _conn;
+ }
- std::string getHost() const { return _host; }
+ bool ok() const {
+ return _conn != NULL;
+ }
- /** Force closure of the connection. You should call this if you leave it in
- a bad state. Destructor will do this too, but it is verbose.
- */
- void kill() {
- delete _conn;
- _conn = 0;
- }
+ std::string getHost() const {
+ return _host;
+ }
- /** Call this when you are done with the connection.
+ /** Force closure of the connection. You should call this if you leave it in
+ a bad state. Destructor will do this too, but it is verbose.
+ */
+ void kill() {
+ delete _conn;
+ _conn = 0;
+ }
- If you do not call done() before this object goes out of scope,
- we can't be sure we fully read all expected data of a reply on the socket. so
- we don't try to reuse the connection in that situation.
- */
- void done();
+ /** Call this when you are done with the connection.
- private:
+ If you do not call done() before this object goes out of scope,
+ we can't be sure we fully read all expected data of a reply on the socket. so
+ we don't try to reuse the connection in that situation.
+ */
+ void done();
- void _setSocketTimeout();
+private:
+ void _setSocketTimeout();
- const std::string _host;
- DBClientBase *_conn;
- const double _socketTimeout;
- };
+ const std::string _host;
+ DBClientBase* _conn;
+ const double _socketTimeout;
+};
-} // namespace mongo
+} // namespace mongo