Files
pgcat/src/pool.rs

87 lines
2.3 KiB
Rust
Raw Normal View History

2022-02-03 16:25:05 -08:00
use async_trait::async_trait;
use bb8::{ManageConnection, PooledConnection};
use crate::errors::Error;
use crate::server::Server;
2022-02-04 16:01:35 -08:00
use crate::ClientServerMap;
2022-02-03 16:25:05 -08:00
pub struct ServerPool {
host: String,
port: String,
user: String,
password: String,
database: String,
2022-02-04 16:01:35 -08:00
client_server_map: ClientServerMap,
2022-02-03 16:25:05 -08:00
}
impl ServerPool {
2022-02-04 16:01:35 -08:00
pub fn new(
host: &str,
port: &str,
user: &str,
password: &str,
database: &str,
client_server_map: ClientServerMap,
) -> ServerPool {
2022-02-03 16:25:05 -08:00
ServerPool {
host: host.to_string(),
port: port.to_string(),
user: user.to_string(),
password: password.to_string(),
database: database.to_string(),
2022-02-04 16:01:35 -08:00
client_server_map: client_server_map,
2022-02-03 16:25:05 -08:00
}
}
}
#[async_trait]
impl ManageConnection for ServerPool {
type Connection = Server;
type Error = Error;
/// Attempts to create a new connection.
2022-02-03 16:25:05 -08:00
async fn connect(&self) -> Result<Self::Connection, Self::Error> {
println!(">> Getting connetion from pool");
2022-02-03 17:33:09 -08:00
//
// TODO: Pick a random connection from a replica pool here.
//
Ok(Server::startup(
&self.host,
&self.port,
&self.user,
&self.password,
&self.database,
2022-02-04 16:01:35 -08:00
self.client_server_map.clone(),
)
.await?)
2022-02-03 16:25:05 -08:00
}
/// Determines if the connection is still connected to the database.
2022-02-03 17:32:04 -08:00
async fn is_valid(&self, conn: &mut PooledConnection<'_, Self>) -> Result<(), Self::Error> {
let server = &mut *conn;
2022-02-03 18:02:50 -08:00
// Client disconnected before cleaning up
if server.in_transaction() {
return Err(Error::DirtyServer);
}
2022-02-03 17:32:04 -08:00
// If this fails, the connection will be closed and another will be grabbed from the pool quietly :-).
// Failover, step 1, complete.
match tokio::time::timeout(
tokio::time::Duration::from_millis(1000),
server.query("SELECT 1"),
)
.await
{
Ok(_) => Ok(()),
Err(_err) => Err(Error::ServerTimeout),
}
2022-02-03 16:25:05 -08:00
}
/// Synchronously determine if the connection is no longer usable, if possible.
fn has_broken(&self, conn: &mut Self::Connection) -> bool {
conn.is_bad()
2022-02-03 16:25:05 -08:00
}
}