mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 10:27:39 +08:00
Optimize connections pool.
This commit is contained in:
parent
7128f97302
commit
f5478d54a4
@ -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&}
|
||||
*/
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace acl {
|
||||
|
||||
tcp_ipc::tcp_ipc(void)
|
||||
tcp_ipc::tcp_ipc()
|
||||
: max_(0)
|
||||
, ttl_(60)
|
||||
, conn_timeout_(10)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "test_stdtab.h"
|
||||
|
||||
void test_stdlib_register()
|
||||
void test_stdlib_register(void)
|
||||
{
|
||||
aut_register(__test_fn_tab);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user