1use crate::error::{QdrantError, QdrantResult};
6use crate::driver::QdrantDriver;
7use std::sync::Arc;
8use tokio::sync::Semaphore;
9
10#[derive(Debug, Clone)]
12pub struct PoolConfig {
13 pub max_connections: usize,
15 pub host: String,
17 pub port: u16,
19}
20
21impl PoolConfig {
22 pub fn new(host: impl Into<String>, port: u16) -> Self {
24 Self {
25 max_connections: 10,
26 host: host.into(),
27 port,
28 }
29 }
30
31 pub fn max_connections(mut self, max: usize) -> Self {
33 self.max_connections = max;
34 self
35 }
36}
37
38impl Default for PoolConfig {
39 fn default() -> Self {
40 Self {
41 max_connections: 10,
42 host: "localhost".to_string(),
43 port: 6334,
44 }
45 }
46}
47
48#[derive(Clone)]
66pub struct QdrantPool {
67 config: Arc<PoolConfig>,
68 semaphore: Arc<Semaphore>,
69}
70
71impl QdrantPool {
72 pub async fn new(config: PoolConfig) -> QdrantResult<Self> {
74 Ok(Self {
75 semaphore: Arc::new(Semaphore::new(config.max_connections)),
76 config: Arc::new(config),
77 })
78 }
79
80 pub async fn get(&self) -> QdrantResult<PooledConnection> {
85 let permit = self.semaphore
86 .clone()
87 .acquire_owned()
88 .await
89 .map_err(|e| QdrantError::Connection(e.to_string()))?;
90
91 let driver = QdrantDriver::connect(&self.config.host, self.config.port).await?;
93
94 Ok(PooledConnection {
95 driver,
96 _permit: permit,
97 })
98 }
99
100 pub fn available(&self) -> usize {
102 self.semaphore.available_permits()
103 }
104
105 pub fn max_connections(&self) -> usize {
107 self.config.max_connections
108 }
109}
110
111pub struct PooledConnection {
113 driver: QdrantDriver,
114 _permit: tokio::sync::OwnedSemaphorePermit,
115}
116
117impl std::ops::Deref for PooledConnection {
118 type Target = QdrantDriver;
119
120 fn deref(&self) -> &Self::Target {
121 &self.driver
122 }
123}
124
125impl std::ops::DerefMut for PooledConnection {
126 fn deref_mut(&mut self) -> &mut Self::Target {
127 &mut self.driver
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn test_pool_config_builder() {
137 let config = PoolConfig::new("localhost", 6334)
138 .max_connections(20);
139
140 assert_eq!(config.max_connections, 20);
141 assert_eq!(config.host, "localhost");
142 assert_eq!(config.port, 6334);
143 }
144
145 #[test]
146 fn test_pool_config_default() {
147 let config = PoolConfig::default();
148 assert_eq!(config.max_connections, 10);
149 assert_eq!(config.host, "localhost");
150 assert_eq!(config.port, 6334);
151 }
152}