Skip to main content

deboa_compio/client/http/conn/
pool.rs

1use 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
14/// Struct that represents the HTTP connection pool.
15///
16/// # Fields
17///
18/// * `connections` - The connections.
19pub 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    /// Allow set max idle connections
43    ///
44    /// # Arguments
45    ///
46    /// * `max_idle_connections` - The max idle connections.
47    ///
48    pub fn set_max_idle_connections(&mut self, max_idle_connections: u32) {
49        self.max_idle_connections = max_idle_connections;
50    }
51
52    /// Allow set keep alive duration
53    ///
54    /// # Arguments
55    ///
56    /// * `keep_alive_duration` - The keep alive duration.
57    ///
58    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}