use std::sync::Arc;
use std::time::Duration;
use ecat_data::{RdbmsClient, RdbmsRouting};
use serde::Deserialize;
use crate::{SqlxClient, SqlxConfig};
fn default_true() -> bool {
true
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SqlxRoutingConfig {
pub primary: SqlxConfig,
#[serde(default)]
pub replicas: Vec<SqlxConfig>,
#[serde(default)]
pub max_replica_lag_secs: Option<u64>,
#[serde(default = "default_true")]
pub fallback_to_primary: bool,
}
pub async fn build_routing(cfg: &SqlxRoutingConfig) -> Result<RdbmsRouting, sqlx::Error> {
let primary = Arc::new(SqlxClient::from_config(cfg.primary.clone()).await?);
let mut replicas: Vec<Arc<dyn RdbmsClient>> = Vec::with_capacity(cfg.replicas.len());
for replica in &cfg.replicas {
replicas.push(Arc::new(SqlxClient::from_config(replica.clone()).await?));
}
let mut routing =
RdbmsRouting::new(primary, replicas).fallback_to_primary(cfg.fallback_to_primary);
if let Some(secs) = cfg.max_replica_lag_secs {
routing = routing.max_replica_lag(Duration::from_secs(secs));
}
Ok(routing)
}
#[cfg(test)]
mod tests;