diff options
author | samantharitter <samantha.ritter@10gen.com> | 2015-09-22 11:19:30 -0400 |
---|---|---|
committer | samantharitter <samantha.ritter@10gen.com> | 2015-10-13 08:34:17 -0400 |
commit | 4877c6b197438495d9fdd88317d4b79d565014c6 (patch) | |
tree | caf9d06036f844774753abbbf68e985378269249 | |
parent | 16d50744c22953720be2cd96fd536c6416d96295 (diff) | |
download | mongo-4877c6b197438495d9fdd88317d4b79d565014c6.tar.gz |
SERVER-20283 Update connPoolStats command to include multiple connection pools
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. */ |