orinium_browser/platform/network/
sender_pool.rs

1//! HTTP Sender Pool.
2//! HTTP/1 と HTTP/2 の Sender を統一的に管理できるプール。
3
4use http_body_util::Empty;
5use hyper::{
6    body::Bytes,
7    client::conn::{http1, http2},
8};
9use std::collections::HashMap;
10
11#[derive(Hash, Eq, PartialEq, Clone, Debug)]
12pub struct HostKey {
13    pub scheme: hyper::http::uri::Scheme,
14    pub host: String,
15    pub port: u16,
16}
17
18/// HTTP/1 と HTTP/2 の Sender を統一的に扱う型
19pub enum HttpSender {
20    Http1(http1::SendRequest<Empty<Bytes>>),
21    Http2(http2::SendRequest<Empty<Bytes>>),
22}
23
24pub struct SenderPool {
25    pool: HashMap<HostKey, Vec<HttpSender>>,
26    max_connections_per_host: usize,
27}
28
29impl Default for SenderPool {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35impl SenderPool {
36    pub fn new() -> Self {
37        Self {
38            pool: HashMap::new(),
39            max_connections_per_host: 6,
40        }
41    }
42
43    pub fn get_connection(&mut self, key: &HostKey) -> Option<HttpSender> {
44        self.pool.get_mut(key).and_then(|v| v.pop())
45    }
46
47    pub fn add_connection(&mut self, key: HostKey, conn: HttpSender) {
48        let entry = self.pool.entry(key).or_default();
49        if entry.len() < self.max_connections_per_host {
50            entry.push(conn);
51        }
52    }
53
54    pub fn remove_connection(&mut self, key: &HostKey) {
55        if let Some(conns) = self.pool.get_mut(key) {
56            conns.pop();
57            if conns.is_empty() {
58                self.pool.remove(key);
59            }
60        }
61    }
62
63    pub fn clear(&mut self) {
64        self.pool.clear();
65    }
66}