deboa_compio/client/http/conn/
pool.rs1use crate::{
2 cert::{DeboaCertificate, DeboaIdentity},
3 client::http::conn::{ConnectionFactory, DeboaConnection},
4};
5use deboa::{
6 conn::ConnectionConfig,
7 dns::DnsResolver,
8 errors::{ConnectionError, DeboaError},
9 Result,
10};
11use hashbrown::HashMap;
12use std::time::Duration;
13
14pub struct HttpConnectionPool {
20 max_idle_connections: u32,
21 keep_alive_duration: Duration,
22 connections: HashMap<String, DeboaConnection>,
23}
24
25impl AsMut<HttpConnectionPool> for HttpConnectionPool {
26 fn as_mut(&mut self) -> &mut HttpConnectionPool {
27 self
28 }
29}
30
31impl Default for HttpConnectionPool {
32 fn default() -> Self {
33 Self {
34 max_idle_connections: 5,
35 keep_alive_duration: Duration::from_mins(5),
36 connections: HashMap::new(),
37 }
38 }
39}
40
41impl HttpConnectionPool {
42 pub fn set_max_idle_connections(&mut self, max_idle_connections: u32) {
49 self.max_idle_connections = max_idle_connections;
50 }
51
52 pub fn set_keep_alive_duration(&mut self, keep_alive_duration: Duration) {
59 self.keep_alive_duration = keep_alive_duration;
60 }
61}
62
63impl deboa::conn::HttpConnectionPool for HttpConnectionPool {
64 type Identity = DeboaIdentity;
65 type Certificate = DeboaCertificate;
66 type ConnectionDispather = DeboaConnection;
67 type ConnectionCache = HashMap<String, DeboaConnection>;
68
69 fn new(max_idle_connections: u32, keep_alive_duration: Duration) -> Self {
70 Self { max_idle_connections, keep_alive_duration, connections: HashMap::new() }
71 }
72
73 #[inline]
74 fn connections(&self) -> &Self::ConnectionCache {
75 &self.connections
76 }
77
78 #[inline]
79 fn connection_count(&self) -> u32 {
80 self.connections
81 .len() as u32
82 }
83
84 async fn create_connection<'a, D>(
85 &mut self,
86 config: &ConnectionConfig<'a, Self::Identity, Self::Certificate>,
87 dns_resolver: &D,
88 ) -> Result<&mut DeboaConnection>
89 where
90 D: DnsResolver,
91 {
92 let host = config.host();
93 if self
94 .connections
95 .contains_key(host)
96 {
97 log::debug!("Connection already exists for {}, reusing.", host);
98 return Ok(self
99 .connections
100 .get_mut(host)
101 .unwrap());
102 }
103
104 log::debug!("Creating new connection for {}", host);
105 let connection = compio::time::timeout(
106 config.connection_timeout(),
107 ConnectionFactory::create_connection(config, dns_resolver),
108 )
109 .await
110 .map_err(|_| {
111 DeboaError::Connection(ConnectionError::Timeout {
112 message: format!(
113 "Connection to {} timed out after {:?}",
114 host,
115 config.connection_timeout()
116 ),
117 })
118 })??;
119
120 self.connections
121 .insert(host.to_string(), connection);
122 Ok(self
123 .connections
124 .get_mut(host)
125 .unwrap())
126 }
127}