acl  3.5.3.0
connect_pool.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include <list>
4 #include "../stdlib/locker.hpp"
5 #include "../stdlib/noncopyable.hpp"
6 
7 namespace acl
8 {
9 
10 class connect_manager;
11 class connect_client;
12 
13 /**
14  * 客户端连接池类,实现对连接池的动态管理,该类为纯虚类,需要子类实现
15  * 纯虚函数 create_connect 用于创建与服务端的一个连接,当允许该类
16  * 对象允许通过 set_delay_destroy() 设置延迟销毁时,该类的子类实例
17  * 必须是动态对象
18  */
20 {
21 public:
22  /**
23  * 构造函数
24  * @param addr {const char*} 服务器监听地址,格式:ip:port(domain:port)
25  * @param max {size_t} 连接池最大连接个数限制,如果该值设为 0,则不设置
26  * 连接池的连接上限
27  * @param idx {size_t} 该连接池对象在集合中的下标位置(从 0 开始)
28  */
29  connect_pool(const char* addr, size_t max, size_t idx = 0);
30 
31  /**
32  * 该类当允许自行销毁时,类实例应为动态对象
33  */
34  virtual ~connect_pool();
35 
36  /**
37  * 此接口用来设置超时时间
38  * @param conn_timeout {int} 网络连接超时时间(秒)
39  * @param rw_timeout {int} 网络 IO 超时时间(秒)
40  */
41  connect_pool& set_timeout(int conn_timeout, int rw_timeout);
42 
43  /**
44  * 设置连接池异常的重试时间间隔
45  * @param retry_inter {int} 当连接断开后,重新再次打开连接的时间间隔(秒),
46  * 当该值 <= 0 时表示允许连接断开后可以立即重连,否则必须超过该时间间隔
47  * 后才允许断开重连;未调用本函数时,内部缺省值为 1 秒
48  * @return {connect_pool&}
49  */
50  connect_pool& set_retry_inter(int retry_inter);
51 
52  /**
53  * 设置连接池中空闲连接的空闲生存周期
54  * @param ttl {time_t} 空闲连接生存周期,当该值 < 0 表示空闲连接不过期,
55  * == 0 时表示立刻过期,> 0 表示空闲该时间段后将被释放
56  * @return {connect_pool&}
57  */
58  connect_pool& set_idle_ttl(time_t ttl);
59 
60  /**
61  * 设置自动检查空闲连接的时间间隔,缺省值为 30 秒
62  * @param n {int} 时间间隔
63  * @return {connect_pool&}
64  */
65  connect_pool& set_check_inter(int n);
66 
67  /**
68  * 从连接池中尝试性获取一个连接,当服务器不可用、距上次服务端连接异常
69  * 时间间隔未过期或连接池连接个数达到连接上限则将返回 NULL;当创建一个
70  * 新的与服务器的连接时失败,则该连接池会被置为不可用状态
71  * @param on {bool} 该参数决定当连接池没有可用连接时是否创建新的连接,
72  * 如果为 false,则不会创建新连接
73  * @return {connect_client*} 如果为空则表示该服务器连接池对象不可用
74  */
75  connect_client* peek(bool on = true);
76 
77  /**
78  * 将一个不属于当前连接池的连接对象与当前连接池对象绑定,使之从属于当前
79  * 连接池对象
80  * @param conn {redis_client*}
81  */
82  void bind_one(connect_client* conn);
83 
84  /**
85  * 释放一个连接至连接池中,当该连接池对应的服务器不可用或调用者希望关闭
86  * 该连接时,则该连接将会被直接释放
87  * @param conn {redis_client*}
88  * @param keep {bool} 是否针对该连接保持长连接
89  */
90  void put(connect_client* conn, bool keep = true);
91 
92  /**
93  * 检查连接池中空闲的连接,将过期的连接释放掉
94  * @param ttl {time_t} 空闲时间间隔超过此值的连接将被释放
95  * @param exclusive {bool} 内部是否需要加锁
96  * @return {int} 被释放的空闲连接个数
97  */
98  int check_idle(time_t ttl, bool exclusive = true);
99 
100  /**
101  * 设置连接池的存活状态
102  * @param ok {bool} 设置该连接是否正常
103  */
104  void set_alive(bool ok /* true | false */);
105 
106  /**
107  * 检查连接池是否正常,当连接池有问题时,该函数还会检测该连接池是否应该
108  * 自动恢复,如果允许恢复,则将该连接池又置为可用状态
109  * @return {bool} 返回 true 表示当前连接池处于正常状态,否则表示当前
110  * 连接池不可用
111  */
112  bool aliving();
113 
114  /**
115  * 获取连接池的服务器地址
116  * @return {const char*} 返回非空地址
117  */
118  const char* get_addr() const
119  {
120  return addr_;
121  }
122 
123  /**
124  * 获取连接池最大连接数限制,如果返回值为 0 则表示没有最大连接数限制
125  * @return {size_t}
126  */
127  size_t get_max() const
128  {
129  return max_;
130  }
131 
132  /**
133  * 获取连接池当前连接数个数
134  * @return {size_t}
135  */
136  size_t get_count() const
137  {
138  return count_;
139  }
140 
141  /**
142  * 获得该连接池对象在连接池集合中的下标位置
143  * @return {size_t}
144  */
145  size_t get_idx() const
146  {
147  return idx_;
148  }
149 
150  /**
151  * 重置统计计数器
152  * @param inter {int} 统计的时间间隔
153  */
154  void reset_statistics(int inter);
155 
156  /**
157  * 获取该连接池总共被使用的次数
158  */
159  unsigned long long get_total_used() const
160  {
161  return total_used_;
162  }
163 
164  /**
165  * 获取该连接池当前的使用次数
166  * @return {unsigned long long}
167  */
168  unsigned long long get_current_used() const
169  {
170  return current_used_;
171  }
172 
173 public:
174  void set_key(const char* key);
175  const char* get_key(void) const
176  {
177  return key_;
178  }
179 
180 protected:
181  /**
182  * 纯虚函数,需要子类实现
183  * @return {connect_client*}
184  */
185  virtual connect_client* create_connect() = 0;
186 
187  friend class connect_manager;
188 
189  /**
190  * 设置该连接池对象为延迟自销毁,当内部发现引用计数为 0 时会自行销毁
191  */
192  void set_delay_destroy();
193 
194 protected:
195  bool alive_; // 是否属正常
196  bool delay_destroy_; // 是否设置了延迟自销毁
197  // 有问题的服务器的可以重试的时间间隔,不可用连接池对象再次被启用的时间间隔
199  time_t last_dead_; // 该连接池对象上次不可用时的时间截
200 
201  char key_[256]; // 与该连接池相关的 key
202  char addr_[256]; // 连接池对应的服务器地址,IP:PORT
203  int conn_timeout_; // 网络连接超时时间(秒)
204  int rw_timeout_; // 网络 IO 超时时间(秒)
205  size_t idx_; // 该连接池对象在集合中的下标位置
206  size_t max_; // 最大连接数
207  size_t count_; // 当前的连接数
208  time_t idle_ttl_; // 空闲连接的生命周期
209  time_t last_check_; // 上次检查空闲连接的时间截
210  int check_inter_; // 检查空闲连接的时间间隔
211 
212  locker lock_; // 访问 pool_ 时的互斥锁
213  unsigned long long total_used_; // 该连接池的所有访问量
214  unsigned long long current_used_; // 某时间段内的访问量
215  time_t last_; // 上次记录的时间截
216  std::list<connect_client*> pool_; // 连接池集合
217 };
218 
220 {
221 public:
223  : keep_(true), pool_(pool), conn_(NULL)
224  {
225  }
226 
227  virtual ~connect_guard(void)
228  {
229  if (conn_)
230  pool_.put(conn_, keep_);
231  }
232 
233  void set_keep(bool keep)
234  {
235  keep_ = keep;
236  }
237 
239  {
240  conn_ = pool_.peek();
241  return conn_;
242  }
243 
244 protected:
245  bool keep_;
248 };
249 
250 } // namespace acl
std::list< connect_client * > pool_
connect_client * peek(void)
unsigned long long total_used_
size_t get_idx() const
size_t get_count() const
virtual ~connect_guard(void)
unsigned long long current_used_
const char * get_addr() const
unsigned long long get_total_used() const
connect_pool & pool_
#define ACL_CPP_API
size_t get_max() const
void set_keep(bool keep)
connect_guard(connect_pool &pool)
connect_client * conn_
const char * get_key(void) const
unsigned long long get_current_used() const