diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/connpool.cpp | 10 | ||||
-rw-r--r-- | src/mongo/executor/connection_pool.cpp | 25 | ||||
-rw-r--r-- | src/mongo/executor/connection_pool.h | 3 | ||||
-rw-r--r-- | src/mongo/executor/connection_pool_stats.cpp | 61 | ||||
-rw-r--r-- | src/mongo/executor/connection_pool_stats.h | 19 | ||||
-rw-r--r-- | src/mongo/executor/connection_pool_test.cpp | 28 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_asio.cpp | 1 |
7 files changed, 99 insertions, 48 deletions
diff --git a/src/mongo/client/connpool.cpp b/src/mongo/client/connpool.cpp index 6b35ea9f399..52f6c94dafc 100644 --- a/src/mongo/client/connpool.cpp +++ b/src/mongo/client/connpool.cpp @@ -361,11 +361,11 @@ void DBConnectionPool::appendConnectionStats(executor::ConnectionPoolStats* stat invariant(uri.isOK()); HostAndPort host = uri.getValue().getServers().front(); - executor::ConnectionStatsPerHost hostStats{ - static_cast<size_t>(i->second.numInUse()), - static_cast<size_t>(i->second.numAvailable()), - static_cast<size_t>(i->second.numCreated())}; - stats->updateStatsForHost(host, hostStats); + executor::ConnectionStatsPer hostStats{static_cast<size_t>(i->second.numInUse()), + static_cast<size_t>(i->second.numAvailable()), + static_cast<size_t>(i->second.numCreated()), + 0}; + stats->updateStatsForHost("global", host, hostStats); } } } diff --git a/src/mongo/executor/connection_pool.cpp b/src/mongo/executor/connection_pool.cpp index 32b83d3348d..010a57973e7 100644 --- a/src/mongo/executor/connection_pool.cpp +++ b/src/mongo/executor/connection_pool.cpp @@ -95,6 +95,11 @@ public: size_t availableConnections(const stdx::unique_lock<stdx::mutex>& lk); /** + * Returns the number of in progress connections in the pool. + */ + size_t refreshingConnections(const stdx::unique_lock<stdx::mutex>& lk); + + /** * Returns the total number of connections ever created in this pool. */ size_t createdConnections(const stdx::unique_lock<stdx::mutex>& lk); @@ -174,8 +179,10 @@ Milliseconds const ConnectionPool::kDefaultHostTimeout = Minutes(5); const Status ConnectionPool::kConnectionStateUnknown = Status(ErrorCodes::InternalError, "Connection is in an unknown state"); -ConnectionPool::ConnectionPool(std::unique_ptr<DependentTypeFactoryInterface> impl, Options options) - : _options(std::move(options)), _factory(std::move(impl)) {} +ConnectionPool::ConnectionPool(std::unique_ptr<DependentTypeFactoryInterface> impl, + std::string name, + Options options) + : _name(std::move(name)), _options(std::move(options)), _factory(std::move(impl)) {} ConnectionPool::~ConnectionPool() = default; @@ -220,10 +227,11 @@ void ConnectionPool::appendConnectionStats(ConnectionPoolStats* stats) const { HostAndPort host = kv.first; auto& pool = kv.second; - ConnectionStatsPerHost hostStats{pool->inUseConnections(lk), - pool->availableConnections(lk), - pool->createdConnections(lk)}; - stats->updateStatsForHost(host, hostStats); + ConnectionStatsPer hostStats{pool->inUseConnections(lk), + pool->availableConnections(lk), + pool->createdConnections(lk), + pool->refreshingConnections(lk)}; + stats->updateStatsForHost(_name, host, hostStats); } } @@ -259,6 +267,11 @@ size_t ConnectionPool::SpecificPool::availableConnections( return _readyPool.size(); } +size_t ConnectionPool::SpecificPool::refreshingConnections( + const stdx::unique_lock<stdx::mutex>& lk) { + return _processingPool.size(); +} + size_t ConnectionPool::SpecificPool::createdConnections(const stdx::unique_lock<stdx::mutex>& lk) { return _created; } diff --git a/src/mongo/executor/connection_pool.h b/src/mongo/executor/connection_pool.h index 80817130ce9..a7b1428ca99 100644 --- a/src/mongo/executor/connection_pool.h +++ b/src/mongo/executor/connection_pool.h @@ -110,6 +110,7 @@ public: }; explicit ConnectionPool(std::unique_ptr<DependentTypeFactoryInterface> impl, + std::string name, Options options = Options{}); ~ConnectionPool(); @@ -123,6 +124,8 @@ public: private: void returnConnection(ConnectionInterface* connection); + std::string _name; + // Options are set at startup and never changed at run time, so these are // accessed outside the lock const Options _options; diff --git a/src/mongo/executor/connection_pool_stats.cpp b/src/mongo/executor/connection_pool_stats.cpp index 02ff34da6c1..64cc3bbc6eb 100644 --- a/src/mongo/executor/connection_pool_stats.cpp +++ b/src/mongo/executor/connection_pool_stats.cpp @@ -36,44 +36,73 @@ namespace mongo { namespace executor { -ConnectionStatsPerHost::ConnectionStatsPerHost(size_t nInUse, size_t nAvailable, size_t nCreated) - : inUse(nInUse), available(nAvailable), created(nCreated) {} +ConnectionStatsPer::ConnectionStatsPer(size_t nInUse, + size_t nAvailable, + size_t nCreated, + size_t nRefreshing) + : inUse(nInUse), available(nAvailable), created(nCreated), refreshing(nRefreshing) {} -ConnectionStatsPerHost::ConnectionStatsPerHost() = default; +ConnectionStatsPer::ConnectionStatsPer() = default; -ConnectionStatsPerHost& ConnectionStatsPerHost::operator+=(const ConnectionStatsPerHost& other) { +ConnectionStatsPer& ConnectionStatsPer::operator+=(const ConnectionStatsPer& other) { inUse += other.inUse; available += other.available; created += other.created; + refreshing += other.refreshing; return *this; } -void ConnectionPoolStats::updateStatsForHost(HostAndPort host, ConnectionStatsPerHost newStats) { +void ConnectionPoolStats::updateStatsForHost(std::string pool, + HostAndPort host, + ConnectionStatsPer newStats) { // Update stats for this host. - auto hostStats = mapFindWithDefault(statsByHost, host); - hostStats += newStats; - statsByHost.insert(std::make_pair(host, hostStats)); + statsByPool[pool] += newStats; + statsByHost[host] += newStats; + statsByPoolHost[pool][host] += newStats; // Update total connection stats. totalInUse += newStats.inUse; totalAvailable += newStats.available; totalCreated += newStats.created; + totalRefreshing += newStats.refreshing; } void ConnectionPoolStats::appendToBSON(mongo::BSONObjBuilder& result) { result.appendNumber("totalInUse", totalInUse); result.appendNumber("totalAvailable", totalAvailable); result.appendNumber("totalCreated", totalCreated); + result.appendNumber("totalRefreshing", totalRefreshing); - BSONObjBuilder hostBuilder(result.subobjStart("hosts")); - for (auto&& host : statsByHost) { - BSONObjBuilder hostInfo(hostBuilder.subobjStart(host.first.toString())); - - auto hostStats = host.second; - hostInfo.appendNumber("inUse", hostStats.inUse); - hostInfo.appendNumber("available", hostStats.available); - hostInfo.appendNumber("created", hostStats.created); + { + BSONObjBuilder poolBuilder(result.subobjStart("pools")); + for (auto&& pool : statsByPool) { + BSONObjBuilder poolInfo(poolBuilder.subobjStart(pool.first)); + auto poolStats = pool.second; + poolInfo.appendNumber("poolInUse", poolStats.inUse); + poolInfo.appendNumber("poolAvailable", poolStats.available); + poolInfo.appendNumber("poolCreated", poolStats.created); + poolInfo.appendNumber("poolRefreshing", poolStats.refreshing); + for (auto&& host : statsByPoolHost[pool.first]) { + BSONObjBuilder hostInfo(poolInfo.subobjStart(host.first.toString())); + auto hostStats = host.second; + hostInfo.appendNumber("inUse", hostStats.inUse); + hostInfo.appendNumber("available", hostStats.available); + hostInfo.appendNumber("created", hostStats.created); + hostInfo.appendNumber("refreshing", hostStats.refreshing); + } + } + } + { + BSONObjBuilder hostBuilder(result.subobjStart("hosts")); + for (auto&& host : statsByHost) { + BSONObjBuilder hostInfo(hostBuilder.subobjStart(host.first.toString())); + auto hostStats = host.second; + hostInfo.appendNumber("inUse", hostStats.inUse); + hostInfo.appendNumber("available", hostStats.available); + hostInfo.appendNumber("created", hostStats.created); + hostInfo.appendNumber("refreshing", hostStats.refreshing); + } } } diff --git a/src/mongo/executor/connection_pool_stats.h b/src/mongo/executor/connection_pool_stats.h index dfdfb71205c..651e821740a 100644 --- a/src/mongo/executor/connection_pool_stats.h +++ b/src/mongo/executor/connection_pool_stats.h @@ -35,19 +35,20 @@ namespace mongo { namespace executor { /** - * Holds connection information for a specific remote host. These objects are maintained by + * Holds connection information for a specific pool or remote host. These objects are maintained by * a parent ConnectionPoolStats object and should not need to be created directly. */ -struct ConnectionStatsPerHost { - ConnectionStatsPerHost(size_t nInUse, size_t nAvailable, size_t nCreated); +struct ConnectionStatsPer { + ConnectionStatsPer(size_t nInUse, size_t nAvailable, size_t nCreated, size_t nRefreshing); - ConnectionStatsPerHost(); + ConnectionStatsPer(); - ConnectionStatsPerHost& operator+=(const ConnectionStatsPerHost& other); + ConnectionStatsPer& operator+=(const ConnectionStatsPer& other); size_t inUse = 0u; size_t available = 0u; size_t created = 0u; + size_t refreshing = 0u; }; /** @@ -56,15 +57,19 @@ struct ConnectionStatsPerHost { * Total connection counts will then be updated accordingly. */ struct ConnectionPoolStats { - void updateStatsForHost(HostAndPort host, ConnectionStatsPerHost newStats); + void updateStatsForHost(std::string pool, HostAndPort host, ConnectionStatsPer newStats); void appendToBSON(mongo::BSONObjBuilder& result); size_t totalInUse = 0u; size_t totalAvailable = 0u; size_t totalCreated = 0u; + size_t totalRefreshing = 0u; - stdx::unordered_map<HostAndPort, ConnectionStatsPerHost> statsByHost; + stdx::unordered_map<std::string, ConnectionStatsPer> statsByPool; + stdx::unordered_map<HostAndPort, ConnectionStatsPer> statsByHost; + stdx::unordered_map<std::string, stdx::unordered_map<HostAndPort, ConnectionStatsPer>> + statsByPoolHost; }; } // namespace executor diff --git a/src/mongo/executor/connection_pool_test.cpp b/src/mongo/executor/connection_pool_test.cpp index 5f7cf6676da..2528d561e85 100644 --- a/src/mongo/executor/connection_pool_test.cpp +++ b/src/mongo/executor/connection_pool_test.cpp @@ -66,7 +66,7 @@ private: * another. */ TEST_F(ConnectionPoolTest, SameConn) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); // Grab and stash an id for the first request size_t conn1Id = 0; @@ -98,7 +98,7 @@ TEST_F(ConnectionPoolTest, SameConn) { * Verify that a failed connection isn't returned to the pool */ TEST_F(ConnectionPoolTest, FailedConnDifferentConn) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); // Grab the first connection and indicate that it failed size_t conn1Id = 0; @@ -131,7 +131,7 @@ TEST_F(ConnectionPoolTest, FailedConnDifferentConn) { * connections. */ TEST_F(ConnectionPoolTest, DifferentHostDifferentConn) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); // Conn 1 from port 30000 size_t conn1Id = 0; @@ -163,7 +163,7 @@ TEST_F(ConnectionPoolTest, DifferentHostDifferentConn) { * Verify that not returning handle's to the pool spins up new connections. */ TEST_F(ConnectionPoolTest, DifferentConnWithoutReturn) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); // Get the first connection, move it out rather than letting it return ConnectionPool::ConnectionHandle conn1; @@ -199,7 +199,7 @@ TEST_F(ConnectionPoolTest, DifferentConnWithoutReturn) { * Note that the lack of pushSetup() calls delays the get. */ TEST_F(ConnectionPoolTest, TimeoutOnSetup) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); bool notOk = false; @@ -234,7 +234,7 @@ TEST_F(ConnectionPoolTest, refreshHappens) { ConnectionPool::Options options; options.refreshRequirement = Milliseconds(1000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -270,7 +270,7 @@ TEST_F(ConnectionPoolTest, refreshTimeoutHappens) { ConnectionPool::Options options; options.refreshRequirement = Milliseconds(1000); options.refreshTimeout = Milliseconds(2000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -338,7 +338,7 @@ TEST_F(ConnectionPoolTest, refreshTimeoutHappens) { * Verify that requests are served in expiration order, not insertion order */ TEST_F(ConnectionPoolTest, requestsServedByUrgency) { - ConnectionPool pool(stdx::make_unique<PoolImpl>()); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool"); bool reachedA = false; bool reachedB = false; @@ -385,7 +385,7 @@ TEST_F(ConnectionPoolTest, maxPoolRespected) { ConnectionPool::Options options; options.minConnections = 1; options.maxConnections = 2; - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); ConnectionPool::ConnectionHandle conn1; ConnectionPool::ConnectionHandle conn2; @@ -445,7 +445,7 @@ TEST_F(ConnectionPoolTest, minPoolRespected) { options.maxConnections = 3; options.refreshRequirement = Milliseconds(1000); options.refreshTimeout = Milliseconds(2000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -554,7 +554,7 @@ TEST_F(ConnectionPoolTest, hostTimeoutHappens) { options.refreshRequirement = Milliseconds(5000); options.refreshTimeout = Milliseconds(5000); options.hostTimeout = Milliseconds(1000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -603,7 +603,7 @@ TEST_F(ConnectionPoolTest, hostTimeoutHappensMoreGetsDelay) { options.refreshRequirement = Milliseconds(5000); options.refreshTimeout = Milliseconds(5000); options.hostTimeout = Milliseconds(1000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -665,7 +665,7 @@ TEST_F(ConnectionPoolTest, hostTimeoutHappensCheckoutDelays) { options.refreshRequirement = Milliseconds(5000); options.refreshTimeout = Milliseconds(5000); options.hostTimeout = Milliseconds(1000); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); @@ -745,7 +745,7 @@ TEST_F(ConnectionPoolTest, dropConnections) { options.maxConnections = 1; options.refreshRequirement = Seconds(1); options.refreshTimeout = Seconds(2); - ConnectionPool pool(stdx::make_unique<PoolImpl>(), options); + ConnectionPool pool(stdx::make_unique<PoolImpl>(), "test pool", options); auto now = Date_t::now(); PoolImpl::setNow(now); diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp index 8021562d511..517fb691f21 100644 --- a/src/mongo/executor/network_interface_asio.cpp +++ b/src/mongo/executor/network_interface_asio.cpp @@ -71,6 +71,7 @@ NetworkInterfaceASIO::NetworkInterfaceASIO(Options options) _timerFactory(std::move(_options.timerFactory)), _streamFactory(std::move(_options.streamFactory)), _connectionPool(stdx::make_unique<connection_pool_asio::ASIOImpl>(this), + _options.instanceName, _options.connectionPoolOptions), _isExecutorRunnable(false), _strand(_io_service) {} |