1use std::collections::VecDeque;
2use std::sync::atomic::AtomicU64;
3use std::time::Instant;
4
5use crate::h2::client::H2Client;
6#[cfg(feature = "http3")]
7use crate::quic::H3Client;
8
9use crate::pool::h1::H1Io;
10
11#[derive(Debug, Clone, Default)]
12#[non_exhaustive]
13pub struct TlsInfo {
14 pub peer_cert_der: Option<Vec<u8>>,
15 pub version: Option<String>,
16 pub cipher: Option<String>,
17}
18
19#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
20pub(crate) enum Transport {
21 Tcp,
22 #[cfg_attr(not(feature = "http3"), allow(dead_code))]
23 Quic,
24}
25
26#[derive(Debug, Clone, Hash, PartialEq, Eq)]
27pub(crate) struct PoolKey {
28 pub(crate) host: String,
29 pub(crate) port: u16,
30 pub(crate) scheme: String,
31 pub(crate) proxy: Option<String>,
32 pub(crate) transport: Transport,
33}
34
35pub struct H1Slot {
36 pub(crate) io: Box<dyn H1Io>,
37}
38
39pub(crate) enum PooledConn {
40 H2 {
41 handle: H2Client,
42 last_use: Instant,
43 tls: TlsInfo,
44 },
45 H1 {
46 idle: VecDeque<(H1Slot, Instant)>,
47 last_use: Instant,
48 tls: TlsInfo,
49 },
50 #[cfg(feature = "http3")]
51 H3 {
52 handle: H3Client,
53 last_use: Instant,
54 tls: TlsInfo,
55 },
56}
57
58impl PooledConn {
59 pub(crate) fn last_use(&self) -> Instant {
60 match self {
61 PooledConn::H2 { last_use, .. } | PooledConn::H1 { last_use, .. } => *last_use,
62 #[cfg(feature = "http3")]
63 PooledConn::H3 { last_use, .. } => *last_use,
64 }
65 }
66
67 pub(crate) fn set_last_use(&mut self, now: Instant) {
68 match self {
69 PooledConn::H2 { last_use, .. } | PooledConn::H1 { last_use, .. } => *last_use = now,
70 #[cfg(feature = "http3")]
71 PooledConn::H3 { last_use, .. } => *last_use = now,
72 }
73 }
74
75 pub(crate) fn is_dead(&self) -> bool {
76 match self {
77 PooledConn::H2 { handle, .. } => handle.is_closed(),
78 PooledConn::H1 { idle, .. } => idle.is_empty(),
79 #[cfg(feature = "http3")]
80 PooledConn::H3 { handle, .. } => handle.is_closed(),
81 }
82 }
83}
84
85#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
86#[non_exhaustive]
87pub struct PoolStats {
88 pub entries: usize,
89 pub max_connections: usize,
90 pub h2_hits: u64,
91 pub h2_misses: u64,
92 pub h1_hits: u64,
93 pub h1_misses: u64,
94 pub h3_hits: u64,
95 pub h3_misses: u64,
96 pub evictions_idle: u64,
97 pub evictions_lru: u64,
98 pub evictions_dead: u64,
99 pub stale_probed: u64,
100 pub h2_ping_failures: u64,
101 pub installs: u64,
102}
103
104#[derive(Default)]
105pub(crate) struct PoolCounters {
106 pub(crate) h2_hits: AtomicU64,
107 pub(crate) h2_misses: AtomicU64,
108 pub(crate) h1_hits: AtomicU64,
109 pub(crate) h1_misses: AtomicU64,
110 pub(crate) h3_hits: AtomicU64,
111 pub(crate) h3_misses: AtomicU64,
112 pub(crate) evictions_idle: AtomicU64,
113 pub(crate) evictions_lru: AtomicU64,
114 pub(crate) evictions_dead: AtomicU64,
115 pub(crate) stale_probed: AtomicU64,
116 pub(crate) h2_ping_failures: AtomicU64,
117 pub(crate) installs: AtomicU64,
118}