Orbit Framework
An ultra-modern, asynchronous, cross-platform C++ Web Framework.
Loading...
Searching...
No Matches
ConnectionPool.hpp
Go to the documentation of this file.
1#pragma once
2#include <vector>
3#include <queue>
4#include <memory>
5#include <functional>
6#include <mutex>
7#include <stdexcept>
9
10namespace database {
11
17template <typename ClientType>
18class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<ClientType>> {
19public:
20 using ClientFactory = std::function<std::shared_ptr<ClientType>()>;
21
28 ConnectionPool(size_t max_size, ClientFactory factory)
29 : max_size_(max_size), factory_(std::move(factory)) {}
30
37 void init(std::function<void(std::shared_ptr<ClientType>, std::function<void(bool)>)> connector, std::function<void(bool success)> on_ready) {
38 if (max_size_ == 0) {
39 on_ready(true);
40 return;
41 }
42
43 auto self = this->shared_from_this();
44 auto success_count = std::make_shared<size_t>(0);
45 auto fail_count = std::make_shared<size_t>(0);
46
47 for (size_t i = 0; i < max_size_; ++i) {
48 auto client = factory_();
49 connector(client, [self, client, on_ready, success_count, fail_count](bool success) {
50 std::lock_guard<std::mutex> lock(self->mutex_);
51 if (success) {
52 self->idle_connections_.push(client);
53 (*success_count)++;
54 } else {
55 (*fail_count)++;
56 }
57
58 if (*success_count + *fail_count == self->max_size_) {
59 on_ready(*fail_count == 0);
60 }
61 });
62 }
63 }
64
70 void acquire(std::function<void(std::shared_ptr<ClientType>)> callback) {
71 std::shared_ptr<ClientType> client = nullptr;
72 {
73 std::lock_guard<std::mutex> lock(mutex_);
74 if (!idle_connections_.empty()) {
75 client = idle_connections_.front();
76 idle_connections_.pop();
77 } else {
78 // Queue the request
79 wait_queue_.push(std::move(callback));
80 return;
81 }
82 }
83 // Invoke callback outside the lock to prevent deadlocks
84 if (client) {
85 callback(client);
86 }
87 }
88
94 void release(std::shared_ptr<ClientType> client) {
95 std::function<void(std::shared_ptr<ClientType>)> next_callback;
96 {
97 std::lock_guard<std::mutex> lock(mutex_);
98 if (!wait_queue_.empty()) {
99 next_callback = std::move(wait_queue_.front());
100 wait_queue_.pop();
101 } else {
102 idle_connections_.push(client);
103 return;
104 }
105 }
106 // Dispatch immediately to next waiter outside the lock
107 if (next_callback) {
108 next_callback(client);
109 }
110 }
111
112private:
113 size_t max_size_;
114 ClientFactory factory_;
115
116 std::mutex mutex_;
117 std::queue<std::shared_ptr<ClientType>> idle_connections_;
118 std::queue<std::function<void(std::shared_ptr<ClientType>)>> wait_queue_;
119};
120
121} // namespace database
A thread-safe connection pool for managing reusable database client connections.
Definition ConnectionPool.hpp:18
ConnectionPool(size_t max_size, ClientFactory factory)
Constructs a new ConnectionPool.
Definition ConnectionPool.hpp:28
std::function< std::shared_ptr< ClientType >()> ClientFactory
Definition ConnectionPool.hpp:20
void acquire(std::function< void(std::shared_ptr< ClientType >)> callback)
Acquires a database connection asynchronously from the pool.
Definition ConnectionPool.hpp:70
void release(std::shared_ptr< ClientType > client)
Releases a connection back to the pool.
Definition ConnectionPool.hpp:94
void init(std::function< void(std::shared_ptr< ClientType >, std::function< void(bool)>)> connector, std::function< void(bool success)> on_ready)
Initializes the pool by establishing the initial set of connections.
Definition ConnectionPool.hpp:37
Definition ConnectionPool.hpp:10
Definition json.hpp:5363