summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@10gen.com>2020-02-27 00:48:13 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-02 19:46:59 +0000
commit15d042e5ce044f136c6d2c6a79d09b23ae838d73 (patch)
tree6a15be952e7c5fa8fe5b5eec0f185f12c17b3ae3
parentb8583f28abf62cf624cd039c6c0aecc8dce653e6 (diff)
downloadmongo-15d042e5ce044f136c6d2c6a79d09b23ae838d73.tar.gz
SERVER-42930 Pools for hosts can outlive their groups
Previously, SpecificPools always were shutdown if their Controller told them they _could_ shutdown. This commit changes the logic to allow SpecificPools to reject their Controller's suggestions if the SpecificPool no longer thinks it is "expired". (cherry picked from commit 2d8f351c2640f402027a2fc0c51628db8d4f85b1)
-rw-r--r--src/mongo/executor/connection_pool.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/mongo/executor/connection_pool.cpp b/src/mongo/executor/connection_pool.cpp
index 00d481b217a..f3f2a61bbb8 100644
--- a/src/mongo/executor/connection_pool.cpp
+++ b/src/mongo/executor/connection_pool.cpp
@@ -39,6 +39,7 @@
#include "mongo/executor/connection_pool_stats.h"
#include "mongo/executor/remote_command_request.h"
#include "mongo/util/assert_util.h"
+#include "mongo/util/debug_util.h"
#include "mongo/util/destructor_guard.h"
#include "mongo/util/log.h"
#include "mongo/util/lru_cache.h"
@@ -71,6 +72,10 @@ void emplaceOrInvariant(Map&& map, Args&&... args) noexcept {
invariant(ret.second, "Element already existed in map/set");
}
+bool shouldInvariantOnPoolCorrectness() noexcept {
+ return kDebugBuild;
+}
+
} // namespace
namespace executor {
@@ -585,8 +590,10 @@ ConnectionPool::SpecificPool::SpecificPool(std::shared_ptr<ConnectionPool> paren
ConnectionPool::SpecificPool::~SpecificPool() {
DESTRUCTOR_GUARD(_eventTimer->cancelTimeout();)
- invariant(_requests.empty());
- invariant(_checkedOutPool.empty());
+ if (shouldInvariantOnPoolCorrectness()) {
+ invariant(_requests.empty());
+ invariant(_checkedOutPool.empty());
+ }
}
size_t ConnectionPool::SpecificPool::inUseConnections() const {
@@ -1075,14 +1082,26 @@ void ConnectionPool::SpecificPool::updateController() {
}
auto& pool = it->second;
+ if (!pool->_health.isExpired) {
+ // Just because a HostGroup "canShutdown" doesn't mean that a SpecificPool should
+ // shutdown. For example, it is always inappropriate to shutdown a SpecificPool with
+ // connections in use or requests outstanding unless its parent ConnectionPool is
+ // also shutting down.
+ warning() << "Controller requested shutdown but connections still in use. "
+ << "Connection pool will stay active. "
+ << "host: " << pool->_hostAndPort;
+ continue;
+ }
// At the moment, controllers will never mark for shutdown a pool with active
// connections or pending requests. isExpired is never true if these invariants are
// false. That's not to say that it's a terrible idea, but if this happens then we
// should review what it means to be expired.
- invariant(pool->_checkedOutPool.empty());
- invariant(pool->_requests.empty());
+ if (shouldInvariantOnPoolCorrectness()) {
+ invariant(pool->_checkedOutPool.empty());
+ invariant(pool->_requests.empty());
+ }
pool->triggerShutdown(Status(ErrorCodes::ShutdownInProgress,
str::stream() << "Pool for " << host << " has expired."));