NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
database_pool.hpp
浏览该文件的文档.
1#ifndef NEFORCE_DATABASE_DATABASE_POOL_HPP__
2#define NEFORCE_DATABASE_DATABASE_POOL_HPP__
3
11
18NEFORCE_BEGIN_NAMESPACE__
19
25
42class NEFORCE_API database_pool {
43public:
48 struct pool_config {
49 size_t init_size = 5;
50 size_t min_size = 5;
51 size_t max_size = 64;
54 };
55
56private:
57 struct connection_entry {
58 idb_connect* conn = nullptr;
59 milliseconds idle_at{0};
60
61 connection_entry() noexcept = default;
62
63 explicit connection_entry(idb_connect* c) :
64 conn(c),
65 idle_at(current_ms()) {}
66
67 NEFORCE_NODISCARD milliseconds idle_duration() const noexcept { return current_ms() - idle_at; }
68
69 static milliseconds current_ms() noexcept { return time_cast<milliseconds>(steady_clock::now().since_epoch()); }
70 };
71
72 db_config config_;
73 pool_config pool_cfg_;
74 unique_ptr<idb_factory> factory_;
75
76 queue<connection_entry> idle_queue_;
77 mutable mutex queue_mtx_;
78 condition_variable cv_;
79
80 atomic<size_t> total_count_{0};
81 atomic<bool> running_{false};
82
83 thread replenish_thread_;
84 thread scanner_thread_;
85
86 idb_connect* try_create_connect() noexcept;
87
88 void return_connect(idb_connect* conn);
89
90 void replenish_task();
91 void scanner_task();
92
93 template <typename T>
94 shared_ptr<T> acquire_impl();
95
96 template <typename T, typename Rep, typename Period>
97 shared_ptr<T> acquire_impl(const duration<Rep, Period>& timeout);
98
99public:
105 database_pool(db_type type, const db_config& config) :
106 database_pool(type, config, pool_config()) {}
107
116
123
124 database_pool(const database_pool&) = delete;
125 database_pool& operator=(const database_pool&) = delete;
126 database_pool(database_pool&&) = delete;
127 database_pool& operator=(database_pool&&) = delete;
128
136
144
152
157 size_t idle_count() const noexcept;
158
163 size_t active_count() const noexcept;
164
169 size_t total_count() const noexcept;
170
178 void warm_up(size_t n);
179
187 template <typename Rep, typename Period>
188 shared_ptr<idb_connect> get_connect_for(const duration<Rep, Period>& timeout) {
189 return acquire_impl<idb_connect>(timeout);
190 }
191
199 template <typename Rep, typename Period>
201 return acquire_impl<idb_tb_connect>(timeout);
202 }
203
211 template <typename Rep, typename Period>
213 return acquire_impl<idb_kv_connect>(timeout);
214 }
215
220 bool is_running() const noexcept { return running_.load(memory_order_acquire); }
221
227 void stop();
228};
229
231template <typename T>
232shared_ptr<T> database_pool::acquire_impl() {
233 unique_lock<mutex> lk(queue_mtx_);
234
235 const bool got = cv_.wait_for(lk, pool_cfg_.acquire_timeout,
236 [this] { return !idle_queue_.empty() || !running_.load(memory_order_relaxed); });
237
238 if (!running_.load(memory_order_relaxed)) {
239 return nullptr;
240 }
241
242 if (!got || idle_queue_.empty()) {
243 const size_t cur = total_count_.load(memory_order_relaxed);
244 if (cur >= pool_cfg_.max_size) {
245 return nullptr;
246 }
247 idb_connect* raw = try_create_connect();
248 if (raw == nullptr) {
249 return nullptr;
250 }
251
252 total_count_.fetch_add(1, memory_order_relaxed);
253 T* typed = dynamic_cast<T*>(raw);
254 if (typed == nullptr) {
255 delete raw;
256 total_count_.fetch_sub(1, memory_order_relaxed);
257 return nullptr;
258 }
259 return shared_ptr<T>(typed, [this](T* p) { this->return_connect(p); });
260 }
261
262 const connection_entry entry = idle_queue_.front();
263 idle_queue_.pop();
264 lk.unlock_quiet();
265 cv_.notify_one();
266
267 idb_connect* raw = entry.conn;
268
269 if (!raw->is_valid()) {
270 if (!raw->reconnect(config_)) {
271 delete raw;
272 total_count_.fetch_sub(1, memory_order_relaxed);
273 cv_.notify_one();
274 return nullptr;
275 }
276 }
277
278 T* typed = dynamic_cast<T*>(raw);
279 if (typed == nullptr) {
280 this->return_connect(raw);
281 return nullptr;
282 }
283
284 return shared_ptr<T>(typed, [this](T* p) { this->return_connect(p); });
285}
286
287template <typename T, typename Rep, typename Period>
288shared_ptr<T> database_pool::acquire_impl(const duration<Rep, Period>& timeout) {
289 unique_lock<mutex> lk(queue_mtx_);
290
291 const bool got =
292 cv_.wait_for(lk, timeout, [this] { return !idle_queue_.empty() || !running_.load(memory_order_relaxed); });
293
294 if (!running_.load(memory_order_relaxed)) {
295 return nullptr;
296 }
297
298 if (!got || idle_queue_.empty()) {
299 const size_t cur = total_count_.load(memory_order_relaxed);
300 if (cur >= pool_cfg_.max_size) {
301 return nullptr;
302 }
303 idb_connect* raw = try_create_connect();
304 if (raw == nullptr) {
305 return nullptr;
306 }
307
308 total_count_.fetch_add(1, memory_order_relaxed);
309 T* typed = dynamic_cast<T*>(raw);
310 if (typed == nullptr) {
311 delete raw;
312 total_count_.fetch_sub(1, memory_order_relaxed);
313 return nullptr;
314 }
315 return shared_ptr<T>(typed, [this](T* p) { this->return_connect(p); });
316 }
317
318 const connection_entry entry = idle_queue_.front();
319 idle_queue_.pop();
320 lk.unlock_quiet();
321 cv_.notify_one();
322
323 idb_connect* raw = entry.conn;
324
325 if (!raw->is_valid()) {
326 if (!raw->reconnect(config_)) {
327 delete raw;
328 total_count_.fetch_sub(1, memory_order_relaxed);
329 cv_.notify_one();
330 return nullptr;
331 }
332 }
333
334 T* typed = dynamic_cast<T*>(raw);
335 if (typed == nullptr) {
336 this->return_connect(raw);
337 return nullptr;
338 }
339
340 return shared_ptr<T>(typed, [this](T* p) { this->return_connect(p); });
341}
343 // Database
345
346NEFORCE_END_NAMESPACE__
347#endif // NEFORCE_DATABASE_DATABASE_POOL_HPP__
原子类型完整实现
void stop()
停止连接池
shared_ptr< idb_tb_connect > get_tb_connect_for(const duration< Rep, Period > &timeout)
获取关系型数据库连接(自定义超时)
shared_ptr< idb_connect > get_connect()
获取通用数据库连接
bool is_running() const noexcept
检查连接池是否正在运行
void warm_up(size_t n)
预热连接池
shared_ptr< idb_kv_connect > get_kv_connect_for(const duration< Rep, Period > &timeout)
获取键值存储连接(自定义超时)
size_t idle_count() const noexcept
获取空闲连接数
size_t total_count() const noexcept
获取总连接数
database_pool(db_type type, const db_config &config, const pool_config &pool_config)
构造函数
database_pool(db_type type, const db_config &config)
构造函数
shared_ptr< idb_kv_connect > get_kv_connect()
获取键值存储连接
size_t active_count() const noexcept
获取活跃连接数
~database_pool()
析构函数
shared_ptr< idb_connect > get_connect_for(const duration< Rep, Period > &timeout)
获取通用数据库连接(自定义超时)
shared_ptr< idb_tb_connect > get_tb_connect()
获取关系型数据库连接
共享智能指针类模板
独占锁管理器模板
条件变量行为
数据库抽象接口层
db_type
数据库类型枚举
duration< int64_t > seconds
秒持续时间
duration< int64_t, milli > milliseconds
毫秒持续时间
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
队列容器适配器
共享智能指针实现
seconds max_idle_time
连接最大空闲时间
milliseconds acquire_timeout
获取连接超时时间
数据库连接配置结构
持续时间类模板
数据库连接抽象基类
线程管理类