Optimize connections pool.

This commit is contained in:
shuxin   zheng 2024-08-19 15:02:32 +08:00
parent 7128f97302
commit f5478d54a4
8 changed files with 101 additions and 52 deletions

View File

@ -63,7 +63,6 @@ public:
* @param on {bool}
* @param kick_dead {bool}
* true connect_client alive()
* @param conns_min {size_t} > 0
* @param step {bool}
* @return {connect_monitor&}
*/

View File

@ -101,19 +101,41 @@ public:
void put(connect_client* conn, bool keep = true);
/**
*
* @param kick_dead {bool}
* 使 set_idle_ttl()
* @param exclusive {bool}
* @return {size_t}
* @param kick_dead {bool}
* @return {size_t}
*/
size_t check_idle(bool kick_dead, bool exclusive);
size_t check_idle(bool kick_dead, bool exclusive = true);
/**
*
*
* @param ttl {time_t} >= 0
* @param exclusive {bool}
* @param kick_dead {bool}
* @return {size_t}
*/
size_t check_idle(time_t ttl, bool kick_dead, bool exclusive = true);
/**
*
* @param ttl {time_t} >= 0
* @param exclusive {bool}
* @return {size_t}
*/
size_t check_idle(time_t ttl, bool exclusive = true);
/**
*
* @param count {size_t} 0
* @return {size_t}
*/
size_t check_dead(bool exclusive = true);
size_t check_dead(size_t count = 0);
/**
* set_conns_min()
*/
void keep_conns();
/**
*
@ -232,13 +254,7 @@ protected:
std::list<connect_client*> pool_; // 连接池集合
size_t kick_idle_conns(time_t ttl); // 关闭过期的连接
/**
*
* @param min {size_t} > 0
* @return {size_t}
*/
size_t keep_conns(size_t min);
connect_client* peek_back(); // 从尾部 Peek 连接
};
class ACL_CPP_API connect_guard : public noncopyable {

View File

@ -324,13 +324,23 @@ void connect_pool::set_alive(bool yes /* true | false */)
lock_.unlock();
}
size_t connect_pool::check_idle(bool kick_dead, bool exclusive)
size_t connect_pool::check_idle(time_t ttl, bool exclusive /* true */)
{
return check_idle(ttl, false, exclusive);
}
size_t connect_pool::check_idle(bool kick_dead, bool exclusive /* true */)
{
return check_idle(idle_ttl_, kick_dead, exclusive);
}
size_t connect_pool::check_idle(time_t ttl, bool kick_dead, bool exclusive)
{
if (exclusive) {
lock_.lock();
}
if (pool_.empty()) {
if (pool_.empty() && min_ == 0) {
if (exclusive) {
lock_.unlock();
}
@ -339,7 +349,7 @@ size_t connect_pool::check_idle(bool kick_dead, bool exclusive)
size_t n = 0;
if (idle_ttl_ == 0) {
if (ttl == 0) {
std::list<connect_client*>::iterator it = pool_.begin();
for (; it != pool_.end(); ++it) {
delete *it;
@ -355,22 +365,24 @@ size_t connect_pool::check_idle(bool kick_dead, bool exclusive)
return n;
}
if (idle_ttl_ > 0) {
n += kick_idle_conns(idle_ttl_);
if (ttl > 0) {
n += kick_idle_conns(ttl);
}
if (kick_dead) {
n += check_dead(false);
}
if (min_ > 0) {
keep_conns(min_);
}
size_t count = count_;
if (exclusive) {
lock_.unlock();
}
if (kick_dead) {
n += check_dead(count);
}
if (min_ > 0) {
keep_conns();
}
return n;
}
@ -414,62 +426,85 @@ size_t connect_pool::kick_idle_conns(time_t ttl)
return n;
}
size_t connect_pool::check_dead(bool exclusive /* true */)
size_t connect_pool::check_dead(size_t count /* 0 */)
{
if (exclusive) {
if (count == 0) {
lock_.lock();
count = count_;
lock_.unlock();
}
size_t n = 0;
std::list<connect_client*>::iterator it;
for (size_t i = 0; i < count; i++) {
connect_client* conn = peek_back();
if (conn == NULL) {
break;
}
// Check all the dead connections and close them.
for (it = pool_.begin(); it != pool_.end();) {
if ((*it)->alive()) {
++it;
if (conn->alive()) {
put(conn);
continue;
}
if ((*it)->get_pool() == this) {
count_--;
if (conn->get_pool() == this) {
lock_.lock();
--count_;
lock_.unlock();
}
delete *it;
it = pool_.erase(it);
delete conn;
n++;
}
if (exclusive) {
lock_.unlock();
}
return n;
}
size_t connect_pool::keep_conns(size_t min)
connect_client* connect_pool::peek_back()
{
if (min > 0 && min > count_) {
min -= count_;
lock_.lock();
std::list<connect_client*>::reverse_iterator rit = pool_.rbegin();
if (rit == pool_.rend()) {
lock_.unlock();
return NULL;
}
std::list<connect_client*>::iterator it = --rit.base();
connect_client* conn = *it;
pool_.erase(it);
lock_.unlock();
return conn;
}
void connect_pool::keep_conns()
{
lock_.lock();
size_t min;
if (min_ > 0 && min_ > count_) {
min = min_ - count_;
} else {
min = 0;
}
lock_.unlock();
for (size_t i = 0; i < min; i++) {
connect_client* conn = create_connect();
if (conn == NULL) {
logger_error("Create connection error");
break;
}
if (!conn->open()) {
logger_error("Open connection error, conn=%p", conn);
logger_error("Open error: %s", last_serror());
delete conn;
break;
}
lock_.lock();
count_++;
lock_.unlock();
conn->set_pool(this);
put(conn, true);
}
return count_;
}
} // namespace acl

View File

@ -10,7 +10,7 @@
namespace acl {
tcp_ipc::tcp_ipc(void)
tcp_ipc::tcp_ipc()
: max_(0)
, ttl_(60)
, conn_timeout_(10)

View File

@ -8,7 +8,7 @@
#include "test_net.h"
#include "test_nettab.h"
void test_net_register()
void test_net_register(void)
{
aut_register(__test_fn_tab);
}

View File

@ -53,7 +53,7 @@ int test_avl_create(AUT_LINE *test_line acl_unused, void *arg acl_unused)
int test_avl_add_bat(AUT_LINE *test_line acl_unused, void *arg acl_unused)
{
MY_TYPE *pm, m;
int i, n = 0;
int i;
for (i = 0; i < 100; i++) {
snprintf(m.name, sizeof(m.name), "%d", i);
@ -69,7 +69,6 @@ int test_avl_add_bat(AUT_LINE *test_line acl_unused, void *arg acl_unused)
snprintf(pm->value, sizeof(pm->value), "value(%d)", i);
acl_avl_add(__avl_tree, pm);
printf(">>add one, key(%s), value(%s)\r\n", pm->name, pm->value);
n++;
}
return (0);

View File

@ -9,7 +9,7 @@
#include "test_stdtab.h"
void test_stdlib_register()
void test_stdlib_register(void)
{
aut_register(__test_fn_tab);
}

View File

@ -3,7 +3,7 @@
#include "unit_test.h"
#include "unit_test_tab.h"
void test_unit_register()
void test_unit_register(void)
{
aut_register(__test_fn_tab);
}