Line data Source code
1 : #ifndef THINGER_HTTP_CLIENT_CONNECTION_POOL_HPP
2 : #define THINGER_HTTP_CLIENT_CONNECTION_POOL_HPP
3 :
4 : #include <memory>
5 : #include <string>
6 : #include <shared_mutex>
7 : #include <boost/multi_index_container.hpp>
8 : #include <boost/multi_index/member.hpp>
9 : #include <boost/multi_index/composite_key.hpp>
10 : #include <boost/multi_index/hashed_index.hpp>
11 : #include <boost/multi_index/sequenced_index.hpp>
12 : #include "client_connection.hpp"
13 :
14 : namespace thinger::http {
15 :
16 : class connection_pool {
17 : private:
18 : // Connection entry in the pool
19 : struct connection_entry {
20 : std::string host;
21 : uint16_t port;
22 : bool ssl;
23 : std::string unix_socket_path; // Empty for TCP connections
24 : std::weak_ptr<client_connection> connection;
25 :
26 767534 : connection_entry(const std::string& h, uint16_t p, bool s,
27 : const std::string& unix_path,
28 : std::shared_ptr<client_connection> conn)
29 767534 : : host(h), port(p), ssl(s), unix_socket_path(unix_path), connection(conn) {}
30 : };
31 :
32 : // Tags for multi_index_container
33 : struct by_key {};
34 : struct by_sequence {};
35 :
36 : // Define the multi_index_container with composite key indexing
37 : using connection_container = boost::multi_index_container<
38 : connection_entry,
39 : boost::multi_index::indexed_by<
40 : // Hashed index by composite key (host, port, ssl, unix_socket_path)
41 : boost::multi_index::hashed_unique<
42 : boost::multi_index::tag<by_key>,
43 : boost::multi_index::composite_key<
44 : connection_entry,
45 : boost::multi_index::member<connection_entry, std::string, &connection_entry::host>,
46 : boost::multi_index::member<connection_entry, uint16_t, &connection_entry::port>,
47 : boost::multi_index::member<connection_entry, bool, &connection_entry::ssl>,
48 : boost::multi_index::member<connection_entry, std::string, &connection_entry::unix_socket_path>
49 : >
50 : >,
51 : // Sequenced index for LRU-style access if needed in future
52 : boost::multi_index::sequenced<
53 : boost::multi_index::tag<by_sequence>
54 : >
55 : >
56 : >;
57 :
58 : connection_container connections_;
59 : mutable std::shared_mutex mutex_;
60 :
61 : public:
62 720 : connection_pool() = default;
63 : ~connection_pool();
64 :
65 : // Get a connection from the pool (returns nullptr if not found or expired)
66 : std::shared_ptr<client_connection> get_connection(const std::string& host,
67 : uint16_t port,
68 : bool ssl);
69 :
70 : // Get a unix socket connection from the pool
71 : std::shared_ptr<client_connection> get_unix_connection(const std::string& unix_path);
72 :
73 : // Store a connection in the pool
74 : void store_connection(const std::string& host,
75 : uint16_t port,
76 : bool ssl,
77 : std::shared_ptr<client_connection> connection);
78 :
79 : // Store a unix socket connection in the pool
80 : void store_unix_connection(const std::string& unix_path,
81 : std::shared_ptr<client_connection> connection);
82 :
83 : // Remove expired connections (optional cleanup method)
84 : // Returns the number of connections removed
85 : size_t cleanup_expired();
86 :
87 : // Get the number of connections in the pool
88 : size_t size() const;
89 :
90 : // Clear all connections from the pool (always closes them)
91 : void clear();
92 :
93 : private:
94 : std::shared_ptr<client_connection> get_connection_impl(const std::string& host,
95 : uint16_t port,
96 : bool ssl,
97 : const std::string& unix_path);
98 :
99 : void store_connection_impl(const std::string& host,
100 : uint16_t port,
101 : bool ssl,
102 : const std::string& unix_path,
103 : std::shared_ptr<client_connection> connection);
104 : };
105 :
106 : } // namespace thinger::http
107 :
108 : #endif // THINGER_HTTP_CLIENT_CONNECTION_POOL_HPP
|