summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsamantharitter <samantha.ritter@10gen.com>2015-09-22 11:19:30 -0400
committersamantharitter <samantha.ritter@10gen.com>2015-10-13 08:34:17 -0400
commit4877c6b197438495d9fdd88317d4b79d565014c6 (patch)
treecaf9d06036f844774753abbbf68e985378269249
parent16d50744c22953720be2cd96fd536c6416d96295 (diff)
downloadmongo-4877c6b197438495d9fdd88317d4b79d565014c6.tar.gz
SERVER-20283 Update connPoolStats command to include multiple connection pools
-rw-r--r--jstests/sharding/conn_pool_stats.js35
-rw-r--r--src/mongo/client/connpool.cpp56
-rw-r--r--src/mongo/client/connpool.h14
-rw-r--r--src/mongo/db/SConscript2
-rw-r--r--src/mongo/db/commands.cpp33
-rw-r--r--src/mongo/db/commands/conn_pool_stats.cpp111
-rw-r--r--src/mongo/db/repl/replication_coordinator.h5
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp4
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h2
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.cpp2
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.h2
-rw-r--r--src/mongo/db/repl/replication_executor.cpp4
-rw-r--r--src/mongo/db/repl/replication_executor.h3
-rw-r--r--src/mongo/executor/connection_pool.cpp76
-rw-r--r--src/mongo/executor/connection_pool.h7
-rw-r--r--src/mongo/executor/network_interface.h8
-rw-r--r--src/mongo/executor/network_interface_asio.cpp4
-rw-r--r--src/mongo/executor/network_interface_asio.h1
-rw-r--r--src/mongo/executor/network_interface_impl.cpp2
-rw-r--r--src/mongo/executor/network_interface_impl.h1
-rw-r--r--src/mongo/executor/network_interface_mock.cpp2
-rw-r--r--src/mongo/executor/network_interface_mock.h1
-rw-r--r--src/mongo/executor/task_executor.h7
-rw-r--r--src/mongo/executor/thread_pool_task_executor.cpp4
-rw-r--r--src/mongo/executor/thread_pool_task_executor.h2
25 files changed, 317 insertions, 71 deletions
diff --git a/jstests/sharding/conn_pool_stats.js b/jstests/sharding/conn_pool_stats.js
new file mode 100644
index 00000000000..52a4b38641d
--- /dev/null
+++ b/jstests/sharding/conn_pool_stats.js
@@ -0,0 +1,35 @@
+// Tests for the connPoolStats command.
+
+// Create a cluster with 2 shards.
+var cluster = new ShardingTest({shards: 2});
+
+// Run the connPoolStats command
+stats = cluster.s.getDB("admin").runCommand({connPoolStats : 1});
+
+// Validate output
+printjson(stats);
+assert.commandWorked(stats);
+assert("replicaSets" in stats);
+
+assert("pools" in stats);
+var pools = stats["pools"];
+
+// Stats from dbclient pool
+assert("DBClient (Global)" in pools);
+var dbclient = pools["DBClient (Global)"];
+assert("hosts" in dbclient);
+assert("numClientConnection" in dbclient);
+assert("numAScopedConnection" in dbclient);
+assert("totalInUse" in dbclient);
+assert("totalAvailable" in dbclient);
+assert("totalCreated" in dbclient);
+assert.eq(dbclient["totalInUse"] + dbclient["totalAvailable"], dbclient["totalCreated"]);
+
+// Stats from ASIO pool
+assert("NetworkInterfaceASIO (Sharding)" in pools);
+var asio = pools["NetworkInterfaceASIO (Sharding)"];
+assert("hosts" in asio);
+assert("totalInUse" in asio);
+assert("totalAvailable" in asio);
+assert("totalCreated" in asio);
+assert.eq(asio["totalInUse"] + asio["totalAvailable"], asio["totalCreated"]);
diff --git a/src/mongo/client/connpool.cpp b/src/mongo/client/connpool.cpp
index e691baafc57..ef070e456d6 100644
--- a/src/mongo/client/connpool.cpp
+++ b/src/mongo/client/connpool.cpp
@@ -67,6 +67,8 @@ void PoolForHost::clear() {
void PoolForHost::done(DBConnectionPool* pool, DBClientBase* c) {
bool isFailed = c->isFailed();
+ --_checkedOut;
+
// Remember that this host had a broken connection for later
if (isFailed)
reportBadConnectionAt(c->getSockCreationMicroSec());
@@ -115,6 +117,7 @@ DBClientBase* PoolForHost::get(DBConnectionPool* pool, double socketTimeout) {
verify(sc.conn->getSoTimeout() == socketTimeout);
+ ++_checkedOut;
return sc.conn;
}
@@ -162,7 +165,10 @@ bool PoolForHost::StoredConnection::ok(time_t now) {
void PoolForHost::createdOne(DBClientBase* base) {
if (_created == 0)
_type = base->type();
- _created++;
+ ++_created;
+ // _checkedOut is used to indicate the number of in-use connections so
+ // though we didn't actually check this connection out, we bump it here.
+ ++_checkedOut;
}
void PoolForHost::initializeHostName(const std::string& hostName) {
@@ -336,11 +342,9 @@ void DBConnectionPool::onDestroy(DBClientBase* conn) {
}
void DBConnectionPool::appendInfo(BSONObjBuilder& b) {
- int avail = 0;
- long long created = 0;
-
-
- map<ConnectionString::ConnectionType, long long> createdByType;
+ int totalInUse = 0;
+ int totalAvailable = 0;
+ long long totalCreated = 0;
BSONObjBuilder bb(b.subobjStart("hosts"));
{
@@ -349,39 +353,29 @@ void DBConnectionPool::appendInfo(BSONObjBuilder& b) {
if (i->second.numCreated() == 0)
continue;
- string s = str::stream() << i->first.ident << "::" << i->first.timeout;
+ auto inUse = i->second.numInUse();
+ auto available = i->second.numAvailable();
+ auto created = i->second.numCreated();
+ string s = str::stream() << i->first.ident << "::" << i->first.timeout;
BSONObjBuilder temp(bb.subobjStart(s));
- temp.append("available", i->second.numAvailable());
- temp.appendNumber("created", i->second.numCreated());
- temp.done();
- avail += i->second.numAvailable();
- created += i->second.numCreated();
+ temp.append("inUse", inUse);
+ temp.append("available", available);
+ temp.appendNumber("created", created);
- long long& x = createdByType[i->second.type()];
- x += i->second.numCreated();
- }
- }
- bb.done();
-
- // Always report all replica sets being tracked
- BSONObjBuilder setBuilder(b.subobjStart("replicaSets"));
- globalRSMonitorManager.report(&setBuilder);
- setBuilder.done();
+ temp.done();
- {
- BSONObjBuilder temp(bb.subobjStart("createdByType"));
- for (map<ConnectionString::ConnectionType, long long>::iterator i = createdByType.begin();
- i != createdByType.end();
- ++i) {
- temp.appendNumber(ConnectionString::typeToString(i->first), i->second);
+ totalInUse += inUse;
+ totalAvailable += available;
+ totalCreated += created;
}
- temp.done();
}
+ bb.done();
- b.append("totalAvailable", avail);
- b.appendNumber("totalCreated", created);
+ b.append("totalInUse", totalInUse);
+ b.append("totalAvailable", totalAvailable);
+ b.appendNumber("totalCreated", totalCreated);
}
bool DBConnectionPool::serverNameCompare::operator()(const string& a, const string& b) const {
diff --git a/src/mongo/client/connpool.h b/src/mongo/client/connpool.h
index a9f494d7279..570510ee2b3 100644
--- a/src/mongo/client/connpool.h
+++ b/src/mongo/client/connpool.h
@@ -39,6 +39,7 @@
namespace mongo {
+class BSONObjBuilder;
class DBConnectionPool;
/**
@@ -54,13 +55,15 @@ public:
: _created(0),
_minValidCreationTimeMicroSec(0),
_type(ConnectionString::INVALID),
- _maxPoolSize(kPoolSizeUnlimited) {}
+ _maxPoolSize(kPoolSizeUnlimited),
+ _checkedOut(0) {}
PoolForHost(const PoolForHost& other)
: _created(other._created),
_minValidCreationTimeMicroSec(other._minValidCreationTimeMicroSec),
_type(other._type),
- _maxPoolSize(other._maxPoolSize) {
+ _maxPoolSize(other._maxPoolSize),
+ _checkedOut(other._checkedOut) {
verify(_created == 0);
verify(other._pool.size() == 0);
}
@@ -85,6 +88,10 @@ public:
return (int)_pool.size();
}
+ int numInUse() const {
+ return _checkedOut;
+ }
+
void createdOne(DBClientBase* base);
long long numCreated() const {
return _created;
@@ -145,6 +152,9 @@ private:
// The maximum number of connections we'll save in the pool
int _maxPoolSize;
+
+ // The number of currently active connections from this pool
+ int _checkedOut;
};
class DBConnectionHook {
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index e0ef1520d61..b495f7ede6a 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -476,6 +476,7 @@ env.Library(
"audit.cpp",
"commands.cpp",
"commands/authentication_commands.cpp",
+ "commands/conn_pool_stats.cpp",
"commands/connection_status.cpp",
"commands/copydb_common.cpp",
"commands/fail_point_cmd.cpp",
@@ -494,6 +495,7 @@ env.Library(
LIBDEPS=[
'$BUILD_DIR/mongo/client/clientdriver',
'$BUILD_DIR/mongo/db/commands/test_commands_enabled',
+ '$BUILD_DIR/mongo/db/repl/repl_coordinator_global',
'$BUILD_DIR/mongo/logger/parse_log_component_settings',
'$BUILD_DIR/mongo/scripting/scripting_common',
'$BUILD_DIR/mongo/util/cmdline_utils/cmdline_utils',
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 32226b4a8fb..ec130328bef 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -535,37 +535,4 @@ public:
} poolFlushCmd;
-class PoolStats : public Command {
-public:
- PoolStats() : Command("connPoolStats") {}
- virtual void help(stringstream& help) const {
- help << "stats about connection pool";
- }
- virtual bool isWriteCommandForConfigServer() const {
- return false;
- }
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::connPoolStats);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
- }
- virtual bool run(OperationContext* txn,
- const string&,
- mongo::BSONObj&,
- int,
- std::string&,
- mongo::BSONObjBuilder& result) {
- globalConnPool.appendInfo(result);
- result.append("numDBClientConnection", DBClientConnection::getNumConnections());
- result.append("numAScopedConnection", AScopedConnection::getNumConnections());
- return true;
- }
- virtual bool slaveOk() const {
- return true;
- }
-
-} poolStatsCmd;
-
} // namespace mongo
diff --git a/src/mongo/db/commands/conn_pool_stats.cpp b/src/mongo/db/commands/conn_pool_stats.cpp
new file mode 100644
index 00000000000..a8e5af9bd64
--- /dev/null
+++ b/src/mongo/db/commands/conn_pool_stats.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include <string>
+#include <vector>
+
+#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/client/connpool.h"
+#include "mongo/client/global_conn_pool.h"
+#include "mongo/db/commands.h"
+#include "mongo/db/repl/replication_coordinator.h"
+#include "mongo/db/repl/replication_coordinator_global.h"
+#include "mongo/executor/network_interface_factory.h"
+#include "mongo/s/client/shard_registry.h"
+#include "mongo/s/grid.h"
+
+namespace mongo {
+
+class PoolStats final : public Command {
+public:
+ PoolStats() : Command("connPoolStats") {}
+
+ void help(std::stringstream& help) const override {
+ help << "stats about connections between servers in a replica set or sharded cluster.";
+ }
+
+ bool isWriteCommandForConfigServer() const override {
+ return false;
+ }
+
+ void addRequiredPrivileges(const std::string& dbname,
+ const BSONObj& cmdObj,
+ std::vector<Privilege>* out) override {
+ ActionSet actions;
+ actions.addAction(ActionType::connPoolStats);
+ out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ }
+
+ bool run(OperationContext* txn,
+ const std::string&,
+ mongo::BSONObj&,
+ int,
+ std::string&,
+ mongo::BSONObjBuilder& result) override {
+ BSONObjBuilder poolStats(result.subobjStart("pools"));
+
+ // Global connection pool
+ BSONObjBuilder globalStats(poolStats.subobjStart("DBClient (Global)"));
+ globalConnPool.appendInfo(globalStats);
+ globalStats.append("numClientConnection", DBClientConnection::getNumConnections());
+ globalStats.append("numAScopedConnection", AScopedConnection::getNumConnections());
+ globalStats.doneFast();
+
+ // Replication ASIO, if we have one
+ auto replCoord = repl::ReplicationCoordinator::get(txn);
+ if (replCoord && replCoord->isReplEnabled()) {
+ BSONObjBuilder replStats(poolStats.subobjStart("NetworkInterfaceASIO (Replication)"));
+ replCoord->appendConnectionStats(&replStats);
+ }
+
+ // Sharding ASIO, if we have one
+ auto registry = grid.shardRegistry();
+ if (registry) {
+ BSONObjBuilder shardStats(poolStats.subobjStart("NetworkInterfaceASIO (Sharding)"));
+ registry->getExecutor()->appendConnectionStats(&shardStats);
+ }
+
+ poolStats.doneFast();
+
+ // Always report all replica sets being tracked
+ BSONObjBuilder setStats(result.subobjStart("replicaSets"));
+ globalRSMonitorManager.report(&setStats);
+ setStats.doneFast();
+
+ return true;
+ }
+
+ bool slaveOk() const override {
+ return true;
+ }
+
+} poolStatsCmd;
+
+} // namespace mongo
diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h
index b24a7453601..03ea6a907a4 100644
--- a/src/mongo/db/repl/replication_coordinator.h
+++ b/src/mongo/db/repl/replication_coordinator.h
@@ -701,6 +701,11 @@ public:
*/
virtual OpTime getCurrentCommittedSnapshotOpTime() = 0;
+ /**
+ * Appends connection information to the provided BSONObjBuilder.
+ */
+ virtual void appendConnectionStats(BSONObjBuilder* b) = 0;
+
protected:
ReplicationCoordinator();
};
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index b4c10c1e420..c9b1f6203d3 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -275,6 +275,10 @@ OpTime ReplicationCoordinatorImpl::getCurrentCommittedSnapshotOpTime() {
return OpTime();
}
+void ReplicationCoordinatorImpl::appendConnectionStats(BSONObjBuilder* b) {
+ _replExecutor.appendConnectionStats(b);
+}
+
void ReplicationCoordinatorImpl::_updateLastVote(const LastVote& lastVote) {
_topCoord->loadLastVote(lastVote);
}
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index 41ee5045be7..018cc7a8539 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -296,6 +296,8 @@ public:
virtual void waitForNewSnapshot(OperationContext* txn) override;
+ virtual void appendConnectionStats(BSONObjBuilder* b) override;
+
// ================== Test support API ===================
/**
diff --git a/src/mongo/db/repl/replication_coordinator_mock.cpp b/src/mongo/db/repl/replication_coordinator_mock.cpp
index 51d33ecbbd5..4750fa28602 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.cpp
+++ b/src/mongo/db/repl/replication_coordinator_mock.cpp
@@ -217,6 +217,8 @@ void ReplicationCoordinatorMock::fillIsMasterForReplSet(IsMasterResponse* result
void ReplicationCoordinatorMock::appendSlaveInfoData(BSONObjBuilder* result) {}
+void ReplicationCoordinatorMock::appendConnectionStats(BSONObjBuilder* b) {}
+
Status ReplicationCoordinatorMock::setMaintenanceMode(bool activate) {
return Status::OK();
}
diff --git a/src/mongo/db/repl/replication_coordinator_mock.h b/src/mongo/db/repl/replication_coordinator_mock.h
index 75149645917..5fbbef2fc51 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.h
+++ b/src/mongo/db/repl/replication_coordinator_mock.h
@@ -127,6 +127,8 @@ public:
virtual void appendSlaveInfoData(BSONObjBuilder* result);
+ void appendConnectionStats(BSONObjBuilder* b) override;
+
virtual ReplicaSetConfig getConfig() const;
virtual void processReplSetGetConfig(BSONObjBuilder* result);
diff --git a/src/mongo/db/repl/replication_executor.cpp b/src/mongo/db/repl/replication_executor.cpp
index 38447f52e65..6dc2067f9ea 100644
--- a/src/mongo/db/repl/replication_executor.cpp
+++ b/src/mongo/db/repl/replication_executor.cpp
@@ -438,6 +438,10 @@ ReplicationExecutor::scheduleWorkWithGlobalExclusiveLock(const CallbackFn& work)
return handle;
}
+void ReplicationExecutor::appendConnectionStats(BSONObjBuilder* b) {
+ _networkInterface->appendConnectionStats(b);
+}
+
std::pair<ReplicationExecutor::WorkItem, ReplicationExecutor::CallbackHandle>
ReplicationExecutor::getWork() {
stdx::unique_lock<stdx::mutex> lk(_mutex);
diff --git a/src/mongo/db/repl/replication_executor.h b/src/mongo/db/repl/replication_executor.h
index 6d1792625c5..67d4debdcc2 100644
--- a/src/mongo/db/repl/replication_executor.h
+++ b/src/mongo/db/repl/replication_executor.h
@@ -50,6 +50,7 @@
namespace mongo {
+class BSONObjBuilder;
class NamespaceString;
class OperationContext;
@@ -124,6 +125,8 @@ public:
void cancel(const CallbackHandle& cbHandle) override;
void wait(const CallbackHandle& cbHandle) override;
+ void appendConnectionStats(BSONObjBuilder* b) override;
+
/**
* Executes the run loop. May be called up to one time.
*
diff --git a/src/mongo/executor/connection_pool.cpp b/src/mongo/executor/connection_pool.cpp
index 0fb0e1ded00..aa5e995600b 100644
--- a/src/mongo/executor/connection_pool.cpp
+++ b/src/mongo/executor/connection_pool.cpp
@@ -29,6 +29,7 @@
#include "mongo/executor/connection_pool.h"
+#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/stdx/memory.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/scopeguard.h"
@@ -57,7 +58,7 @@ public:
~SpecificPool();
/**
- * Get's a connection from the specific pool. Sinks a unique_lock from the
+ * Gets a connection from the specific pool. Sinks a unique_lock from the
* parent to preserve the lock on _mutex
*/
void getConnection(const HostAndPort& hostAndPort,
@@ -66,7 +67,7 @@ public:
GetConnectionCallback cb);
/**
- * Cascade a failure across existing connections and requests. Invoking
+ * Cascades a failure across existing connections and requests. Invoking
* this function drops all current connections and fails all current
* requests with the passed status.
*/
@@ -78,6 +79,21 @@ public:
*/
void returnConnection(ConnectionInterface* connection, stdx::unique_lock<stdx::mutex> lk);
+ /**
+ * Returns the number of connections currently checked out of the pool.
+ */
+ size_t inUseConnections(const stdx::unique_lock<stdx::mutex>& lk);
+
+ /**
+ * Returns the number of available connections in the pool.
+ */
+ size_t availableConnections(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);
+
private:
using OwnedConnection = std::unique_ptr<ConnectionInterface>;
using OwnershipPool = std::unordered_map<ConnectionInterface*, OwnedConnection>;
@@ -118,6 +134,8 @@ private:
size_t _generation;
bool _inFulfillRequests;
+ size_t _created;
+
/**
* The current state of the pool
*
@@ -187,6 +205,44 @@ void ConnectionPool::get(const HostAndPort& hostAndPort,
pool->getConnection(hostAndPort, timeout, std::move(lk), std::move(cb));
}
+void ConnectionPool::appendConnectionStats(BSONObjBuilder* b) {
+ size_t inUse = 0u;
+ size_t available = 0u;
+ size_t created = 0u;
+
+ BSONObjBuilder hostBuilder(b->subobjStart("hosts"));
+
+ stdx::unique_lock<stdx::mutex> lk(_mutex);
+
+ for (const auto& kv : _pools) {
+ std::string label = kv.first.toString();
+ BSONObjBuilder hostInfo(hostBuilder.subobjStart(label));
+
+ auto& pool = kv.second;
+ auto inUseConnections = pool->inUseConnections(lk);
+ auto availableConnections = pool->availableConnections(lk);
+ auto createdConnections = pool->createdConnections(lk);
+ hostInfo.appendNumber("inUse", inUseConnections);
+ hostInfo.appendNumber("available", availableConnections);
+ hostInfo.appendNumber("created", createdConnections);
+
+ hostInfo.done();
+
+ // update available and created
+ inUse += inUseConnections;
+ available += availableConnections;
+ created += createdConnections;
+ }
+
+ hostBuilder.done();
+
+ b->appendNumber("totalInUse", inUse);
+ b->appendNumber("totalAvailable", available);
+ b->appendNumber("totalCreated", created);
+
+ return;
+}
+
void ConnectionPool::returnConnection(ConnectionInterface* conn) {
stdx::unique_lock<stdx::mutex> lk(_mutex);
@@ -203,12 +259,26 @@ ConnectionPool::SpecificPool::SpecificPool(ConnectionPool* parent, const HostAnd
_requestTimer(parent->_factory->makeTimer()),
_generation(0),
_inFulfillRequests(false),
+ _created(0),
_state(State::kRunning) {}
ConnectionPool::SpecificPool::~SpecificPool() {
DESTRUCTOR_GUARD(_requestTimer->cancelTimeout();)
}
+size_t ConnectionPool::SpecificPool::inUseConnections(const stdx::unique_lock<stdx::mutex>& lk) {
+ return _checkedOutPool.size();
+}
+
+size_t ConnectionPool::SpecificPool::availableConnections(
+ const stdx::unique_lock<stdx::mutex>& lk) {
+ return _readyPool.size();
+}
+
+size_t ConnectionPool::SpecificPool::createdConnections(const stdx::unique_lock<stdx::mutex>& lk) {
+ return _created;
+}
+
void ConnectionPool::SpecificPool::getConnection(const HostAndPort& hostAndPort,
Milliseconds timeout,
stdx::unique_lock<stdx::mutex> lk,
@@ -414,6 +484,8 @@ void ConnectionPool::SpecificPool::spawnConnections(stdx::unique_lock<stdx::mute
auto connPtr = handle.get();
_processingPool[connPtr] = std::move(handle);
+ ++_created;
+
// Run the setup callback
lk.unlock();
connPtr->setup(_parent->_options.refreshTimeout,
diff --git a/src/mongo/executor/connection_pool.h b/src/mongo/executor/connection_pool.h
index d46b18b9812..a5d1676bf0e 100644
--- a/src/mongo/executor/connection_pool.h
+++ b/src/mongo/executor/connection_pool.h
@@ -38,6 +38,9 @@
#include "mongo/util/net/hostandport.h"
namespace mongo {
+
+class BSONObjBuilder;
+
namespace executor {
/**
@@ -110,9 +113,7 @@ public:
void get(const HostAndPort& hostAndPort, Milliseconds timeout, GetConnectionCallback cb);
- /**
- * TODO add a function returning connection pool stats
- */
+ void appendConnectionStats(BSONObjBuilder* b);
private:
void returnConnection(ConnectionInterface* connection);
diff --git a/src/mongo/executor/network_interface.h b/src/mongo/executor/network_interface.h
index 8b151b5b54e..8776506b0fe 100644
--- a/src/mongo/executor/network_interface.h
+++ b/src/mongo/executor/network_interface.h
@@ -36,6 +36,9 @@
#include "mongo/stdx/functional.h"
namespace mongo {
+
+class BSONObjBuilder;
+
namespace executor {
/**
@@ -59,6 +62,11 @@ public:
virtual std::string getDiagnosticString() = 0;
/**
+ * Appends connection information to the provided BSONObjBuilder.
+ */
+ virtual void appendConnectionStats(BSONObjBuilder* b) = 0;
+
+ /**
* Starts up the network interface.
*
* It is valid to call all methods except shutdown() before this method completes. That is,
diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp
index 0379738ee93..19f38107de6 100644
--- a/src/mongo/executor/network_interface_asio.cpp
+++ b/src/mongo/executor/network_interface_asio.cpp
@@ -90,6 +90,10 @@ std::string NetworkInterfaceASIO::getDiagnosticString() {
return output;
}
+void NetworkInterfaceASIO::appendConnectionStats(BSONObjBuilder* b) {
+ _connectionPool.appendConnectionStats(b);
+}
+
std::string NetworkInterfaceASIO::getHostName() {
return getHostNameCached();
}
diff --git a/src/mongo/executor/network_interface_asio.h b/src/mongo/executor/network_interface_asio.h
index 2c44039b48c..91fc0858824 100644
--- a/src/mongo/executor/network_interface_asio.h
+++ b/src/mongo/executor/network_interface_asio.h
@@ -100,6 +100,7 @@ public:
NetworkInterfaceASIO(Options = Options());
std::string getDiagnosticString() override;
+ void appendConnectionStats(BSONObjBuilder* b) override;
std::string getHostName() override;
void startup() override;
void shutdown() override;
diff --git a/src/mongo/executor/network_interface_impl.cpp b/src/mongo/executor/network_interface_impl.cpp
index 869ea22d0b2..e7eb502e320 100644
--- a/src/mongo/executor/network_interface_impl.cpp
+++ b/src/mongo/executor/network_interface_impl.cpp
@@ -87,6 +87,8 @@ std::string NetworkInterfaceImpl::getDiagnosticString() {
return output;
}
+void NetworkInterfaceImpl::appendConnectionStats(BSONObjBuilder* b) {}
+
void NetworkInterfaceImpl::startup() {
stdx::unique_lock<stdx::mutex> lk(_mutex);
invariant(!_inShutdown);
diff --git a/src/mongo/executor/network_interface_impl.h b/src/mongo/executor/network_interface_impl.h
index 793e574a552..bc422c59be0 100644
--- a/src/mongo/executor/network_interface_impl.h
+++ b/src/mongo/executor/network_interface_impl.h
@@ -77,6 +77,7 @@ public:
NetworkInterfaceImpl(std::unique_ptr<NetworkConnectionHook> hook);
~NetworkInterfaceImpl();
std::string getDiagnosticString() override;
+ void appendConnectionStats(BSONObjBuilder* b) override;
void startup() override;
void shutdown() override;
void waitForWork() override;
diff --git a/src/mongo/executor/network_interface_mock.cpp b/src/mongo/executor/network_interface_mock.cpp
index d62b13d87ae..fe0aef336be 100644
--- a/src/mongo/executor/network_interface_mock.cpp
+++ b/src/mongo/executor/network_interface_mock.cpp
@@ -63,6 +63,8 @@ std::string NetworkInterfaceMock::getDiagnosticString() {
return "NetworkInterfaceMock diagnostics here";
}
+void NetworkInterfaceMock::appendConnectionStats(BSONObjBuilder* b) {}
+
Date_t NetworkInterfaceMock::now() {
stdx::lock_guard<stdx::mutex> lk(_mutex);
return _now_inlock();
diff --git a/src/mongo/executor/network_interface_mock.h b/src/mongo/executor/network_interface_mock.h
index 0b231295595..8272bf84509 100644
--- a/src/mongo/executor/network_interface_mock.h
+++ b/src/mongo/executor/network_interface_mock.h
@@ -75,6 +75,7 @@ public:
NetworkInterfaceMock();
virtual ~NetworkInterfaceMock();
+ virtual void appendConnectionStats(BSONObjBuilder* b);
virtual std::string getDiagnosticString();
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/mongo/executor/task_executor.h b/src/mongo/executor/task_executor.h
index 74ba98048c4..be7d61b6a1b 100644
--- a/src/mongo/executor/task_executor.h
+++ b/src/mongo/executor/task_executor.h
@@ -43,6 +43,7 @@
namespace mongo {
+class BSONObjBuilder;
class OperationContext;
namespace executor {
@@ -230,6 +231,12 @@ public:
*/
virtual void wait(const CallbackHandle& cbHandle) = 0;
+ /**
+ * Appends information about the underlying network interface's connections to the given
+ * builder.
+ */
+ virtual void appendConnectionStats(BSONObjBuilder* b) = 0;
+
protected:
TaskExecutor();
diff --git a/src/mongo/executor/thread_pool_task_executor.cpp b/src/mongo/executor/thread_pool_task_executor.cpp
index d70c89abfd4..dae256abc09 100644
--- a/src/mongo/executor/thread_pool_task_executor.cpp
+++ b/src/mongo/executor/thread_pool_task_executor.cpp
@@ -342,6 +342,10 @@ void ThreadPoolTaskExecutor::wait(const CallbackHandle& cbHandle) {
waitForEvent(cbState->finishedEvent);
}
+void ThreadPoolTaskExecutor::appendConnectionStats(BSONObjBuilder* b) {
+ _net->appendConnectionStats(b);
+}
+
void ThreadPoolTaskExecutor::cancelAllCommands() {
_net->cancelAllCommands();
}
diff --git a/src/mongo/executor/thread_pool_task_executor.h b/src/mongo/executor/thread_pool_task_executor.h
index e709440dd92..e983c91de49 100644
--- a/src/mongo/executor/thread_pool_task_executor.h
+++ b/src/mongo/executor/thread_pool_task_executor.h
@@ -80,6 +80,8 @@ public:
void cancel(const CallbackHandle& cbHandle) override;
void wait(const CallbackHandle& cbHandle) override;
+ void appendConnectionStats(BSONObjBuilder* b) override;
+
/**
* Cancels all commands on the network interface.
*/