use std::time::Instant;
use crate::connection::stream::PgConnection;
use crate::protocol::backend::BackendMessage;
use crate::protocol::frontend;
pub(crate) async fn check_alive(conn: &mut PgConnection) -> bool {
frontend::query(conn.write_buf(), "");
try_check_alive(conn).await.unwrap_or(false)
}
async fn try_check_alive(conn: &mut PgConnection) -> crate::error::Result<bool> {
conn.send().await?;
loop {
if matches!(conn.recv().await?, BackendMessage::ReadyForQuery { .. }) {
return Ok(true);
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum HealthCheckStrategy {
Fast,
Query,
None,
}
#[derive(Debug)]
pub struct ConnectionMeta {
pub created_at: Instant,
pub last_used: Instant,
pub is_broken: bool,
}
impl Default for ConnectionMeta {
fn default() -> Self {
Self::new()
}
}
impl ConnectionMeta {
pub fn new() -> Self {
let now = Instant::now();
Self {
created_at: now,
last_used: now,
is_broken: false,
}
}
pub fn touch(&mut self) {
self.last_used = Instant::now();
}
pub fn is_idle_expired(&self, timeout: std::time::Duration) -> bool {
self.last_used.elapsed() > timeout
}
pub fn is_lifetime_expired(&self, max_lifetime: std::time::Duration) -> bool {
self.created_at.elapsed() > max_lifetime
}
}