Skip to content

Commit 7dc6dff

Browse files
committed
Bug#34536576 connection-pool does not release connection closed by server
Issue ===== With connection-pool enabled, a connection may get stuck in the pool if it is closed by the server. 1. Start router with - [DEFAULT] max_idle_server_connections=1 - [routing:*] client_ssl_mode=PREFERRED and server_ssl_mode=PREFERRED - max_total_connections=1 2. connect to router and close the connection again (adds the connection to the pool) 3. connect to the server directly and kill the pooled connection - SHOW PROCESSLIST - KILL ... - (should release the connection) 4. connect to router again: fails Change ====== The underlying problem is equality between net::stream_errc::eof from different shared objects failing. The connection-pool's "net::stream_errc::eof"'s .category() refers to a differ "static stream_category" then the one that's passed to connection-pool. That stems from the stream-category being defined in the header which leads to multiple instances of the same "static", one per shared-object. - add a equivalent() method to net::stream_errc's error-category which handles the "multiple instances" case. Change-Id: Iadf74ccbfdee606aff1221740554bcd9dfc04653
1 parent 3626a12 commit 7dc6dff

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

router/src/connection_pool/src/connection_pool.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
#include "mysqlrouter/connection_pool.h"
2626

27-
#include <iostream>
28-
2927
#include "mysql/harness/net_ts/buffer.h"
3028
#include "mysql/harness/net_ts/socket.h"
3129

@@ -37,7 +35,7 @@ void PooledConnection::async_recv_message() {
3735

3836
conn_->async_recv(recv_buf_, [this](std::error_code ec, size_t /* recved */) {
3937
if (ec) {
40-
if (ec == net::stream_errc::eof) {
38+
if (ec == make_error_condition(net::stream_errc::eof)) {
4139
// cancel the timer and let that close the connection.
4240
idle_timer_.cancel();
4341

router/src/harness/include/mysql/harness/net_ts/buffer.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <limits> // std::numeric_limits
3131
#include <stdexcept> // length_error
3232
#include <string>
33+
#include <string_view>
3334
#include <system_error>
3435
#include <type_traits>
3536
#include <utility>
@@ -69,6 +70,28 @@ inline const std::error_category &stream_category() noexcept {
6970
return "unknown";
7071
}
7172
}
73+
74+
bool equivalent(int mycode,
75+
const std::error_condition &other) const noexcept override {
76+
if (*this == other.category() ||
77+
std::string_view(name()) ==
78+
std::string_view(other.category().name())) {
79+
return mycode == other.value();
80+
}
81+
82+
return false;
83+
}
84+
85+
bool equivalent(const std::error_code &other,
86+
int mycode) const noexcept override {
87+
if (*this == other.category() ||
88+
std::string_view(name()) ==
89+
std::string_view(other.category().name())) {
90+
return mycode == other.value();
91+
}
92+
93+
return false;
94+
}
7295
};
7396

7497
static stream_category_impl instance;
@@ -79,6 +102,10 @@ inline std::error_code make_error_code(net::stream_errc e) noexcept {
79102
return {static_cast<int>(e), net::stream_category()};
80103
}
81104

105+
inline std::error_condition make_error_condition(net::stream_errc e) noexcept {
106+
return {static_cast<int>(e), net::stream_category()};
107+
}
108+
82109
// 16.4 [buffer.mutable]
83110

84111
class mutable_buffer {

0 commit comments

Comments
 (0)