use anyhow::Result;
use async_trait::async_trait;
use bytes::Bytes;
use std::collections::HashMap;
pub type Headers = HashMap<String, String>;
#[async_trait]
pub trait RequestPlaneClient: Send + Sync {
async fn send_request(
&self,
address: String,
payload: Bytes,
headers: Headers,
) -> Result<Bytes>;
fn transport_name(&self) -> &'static str;
fn is_healthy(&self) -> bool;
fn stats(&self) -> ClientStats {
ClientStats::default()
}
async fn close(&self) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone, Default)]
pub struct ClientStats {
pub requests_sent: u64,
pub responses_received: u64,
pub errors: u64,
pub bytes_sent: u64,
pub bytes_received: u64,
pub active_connections: usize,
pub idle_connections: usize,
pub avg_latency_us: u64,
}
impl ClientStats {
pub fn new() -> Self {
Self::default()
}
pub fn is_available(&self) -> bool {
self.requests_sent > 0 || self.active_connections > 0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_stats_default() {
let stats = ClientStats::default();
assert_eq!(stats.requests_sent, 0);
assert_eq!(stats.responses_received, 0);
assert!(!stats.is_available());
}
#[test]
fn test_client_stats_is_available() {
let mut stats = ClientStats::default();
assert!(!stats.is_available());
stats.requests_sent = 1;
assert!(stats.is_available());
let stats2 = ClientStats {
active_connections: 1,
..Default::default()
};
assert!(stats2.is_available());
}
}