diff options
Diffstat (limited to 'src/mongo/client/connpool.h')
-rw-r--r-- | src/mongo/client/connpool.h | 102 |
1 files changed, 84 insertions, 18 deletions
diff --git a/src/mongo/client/connpool.h b/src/mongo/client/connpool.h index 68af31a5225..9d428dcab36 100644 --- a/src/mongo/client/connpool.h +++ b/src/mongo/client/connpool.h @@ -37,6 +37,7 @@ #include "mongo/platform/atomic_word.h" #include "mongo/util/background.h" #include "mongo/util/concurrency/mutex.h" +#include "mongo/util/time_support.h" namespace mongo { @@ -52,7 +53,9 @@ struct ConnectionPoolStats; * host. It is not responsible for creating new connections; instead, when DBConnectionPool is asked * for a connection to a particular host, DBConnectionPool will check if any connections are * available in the PoolForHost for that host. If so, DBConnectionPool will check out a connection - * from PoolForHost, and if not, DBConnectionPool will create a new connection itself. + * from PoolForHost, and if not, DBConnectionPool will create a new connection itself, if we are + * below the maximum allowed number of connections. If we have already created _maxPoolSize + * connections, the calling thread will block until a new connection can be made for it. * * Once the connection is released back to DBConnectionPool, DBConnectionPool will attempt to * release the connection to PoolForHost. This is how connections enter PoolForHost for the first @@ -74,15 +77,7 @@ public: friend class DBConnectionPool; - PoolForHost() - : _created(0), - _minValidCreationTimeMicroSec(0), - _type(ConnectionString::INVALID), - _maxPoolSize(kPoolSizeUnlimited), - _checkedOut(0), - _badConns(0), - _parentDestroyed(false) {} - + PoolForHost(); ~PoolForHost(); /** @@ -107,10 +102,17 @@ public: } /** - * Sets the socket timeout on this host, for reporting purposes only. + * Sets the maximum number of in-use connections for this pool. + */ + void setMaxInUse(int maxInUse) { + _maxInUse = maxInUse; + } + + /** + * Sets the socket timeout on this host, in seconds, for reporting purposes only. */ void setSocketTimeout(double socketTimeout) { - _socketTimeout = socketTimeout; + _socketTimeoutSecs = socketTimeout; } int numAvailable() const { @@ -150,7 +152,7 @@ public: void flush(); - void getStaleConnections(std::vector<DBClientBase*>& stale); + void getStaleConnections(Date_t idleThreshold, std::vector<DBClientBase*>& stale); /** * Sets the lower bound for creation times that can be considered as @@ -169,18 +171,45 @@ public: */ void initializeHostName(const std::string& hostName); + /** + * If this pool has more than _maxPoolSize connections in use, blocks + * the calling thread until a connection is returned to the pool or + * is destroyed. If a non-zero timeout is given, this method will + * throw if a free connection cannot be acquired within that amount of + * time. Timeout is in seconds. + */ + void waitForFreeConnection(int timeout, stdx::unique_lock<stdx::mutex>& lk); + + /** + * Notifies any waiters that there are new connections available. + */ + void notifyWaiters(); + + /** + * Shuts down this pool, notifying all waiters. + */ + void shutdown(); + private: struct StoredConnection { StoredConnection(std::unique_ptr<DBClientBase> c); bool ok(); + /** + * Returns true if this connection was added before the given time. + */ + bool addedBefore(Date_t time); + std::unique_ptr<DBClientBase> conn; - time_t when; + + // The time when this connection was added to the pool. Will + // be reset if the connection is checked out and re-added. + Date_t added; }; std::string _hostName; - double _socketTimeout; + double _socketTimeoutSecs; std::stack<StoredConnection> _pool; int64_t _created; @@ -190,6 +219,9 @@ private: // The maximum number of connections we'll save in the pool int _maxPoolSize; + // The maximum number of connections allowed to be in-use in this pool + int _maxInUse; + // The number of currently active connections from this pool int _checkedOut; @@ -198,6 +230,10 @@ private: // Whether our parent DBConnectionPool object is in destruction bool _parentDestroyed; + + stdx::condition_variable _cv; + + AtomicWord<bool> _inShutdown; }; class DBConnectionHook { @@ -259,6 +295,21 @@ public: _maxPoolSize = maxPoolSize; } + /** + * Sets the maximum number of in-use connections per host. + */ + void setMaxInUse(int maxInUse) { + _maxInUse = maxInUse; + } + + /** + * Sets the timeout value for idle connections, after which we will remove them + * from the pool. This value is in minutes. + */ + void setIdleTimeout(int timeout) { + _idleTimeout = Minutes(timeout); + } + void onCreate(DBClientBase* conn); void onHandedOut(DBClientBase* conn); void onDestroy(DBClientBase* conn); @@ -266,6 +317,9 @@ public: void flush(); + /** + * Gets a connection to the given host with the given timeout, in seconds. + */ DBClientBase* get(const std::string& host, double socketTimeout = 0); DBClientBase* get(const ConnectionString& host, double socketTimeout = 0); DBClientBase* get(const MongoURI& uri, double socketTimeout = 0); @@ -310,7 +364,14 @@ public: } virtual void taskDoWork(); + /** + * Shuts down the connection pool, unblocking any waiters on connections. + */ + void shutdown(); + private: + class Detail; + DBConnectionPool(DBConnectionPool& p); DBClientBase* _get(const std::string& ident, double socketTimeout); @@ -337,8 +398,13 @@ private: // 0 effectively disables the pool int _maxPoolSize; + int _maxInUse; + Minutes _idleTimeout; + PoolMap _pools; + AtomicWord<bool> _inShutdown; + // 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; @@ -388,11 +454,11 @@ public: explicit ScopedDbConnection(const ConnectionString& host, double socketTimeout = 0); explicit ScopedDbConnection(const MongoURI& host, double socketTimeout = 0); - ScopedDbConnection() : _host(""), _conn(0), _socketTimeout(0) {} + ScopedDbConnection() : _host(""), _conn(0), _socketTimeoutSecs(0) {} /* @param conn - bind to an existing connection */ ScopedDbConnection(const std::string& host, DBClientBase* conn, double socketTimeout = 0) - : _host(host), _conn(conn), _socketTimeout(socketTimeout) { + : _host(host), _conn(conn), _socketTimeoutSecs(socketTimeout) { _setSocketTimeout(); } @@ -447,7 +513,7 @@ private: const std::string _host; DBClientBase* _conn; - const double _socketTimeout; + const double _socketTimeoutSecs; }; } // namespace mongo |