use anyhow::{Context, Result};
use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex, atomic::Ordering, RwLock};
use std::time::SystemTime;
use std::sync::atomic::Ordering;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CdnProviderType {
Cloudflare,
Vercel,
AWSCloudFront,
Fastly,
}
#[derive(Debug, Clone)]
pub struct CdnEndpoint {
pub id: String,
pub provider: CdnProviderType,
pub region: String,
pub endpoint_url: String,
pub latency: f64, pub status: EndpointStatus,
pub capacity: u64, pub current_load: f64, }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EndpointStatus {
Healthy,
Degraded,
Unhealthy,
Maintenance,
}
#[async_trait::async_trait]
pub trait CdnProvider: Send + Sync {
async fn deploy(&self, code: &[u8], region: &str) -> Result<DeploymentResult>;
async fn route(&self, region: &str) -> Result<CdnEndpoint>;
async fn invalidate_cache(&self, paths: &[&str]) -> Result<()>;
async fn health_check(&self) -> Result<ProviderHealth>;
async fn update_config(&self, config: &HashMap<String, String>) -> Result<()>;
}
#[derive(Debug, Clone)]
pub struct DeploymentResult {
pub deployment_id: String,
pub endpoint_id: String,
pub status: DeploymentStatus,
pub deployment_url: Option<String>,
pub estimated_propagation_time: u64, }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DeploymentStatus {
Pending,
InProgress,
Complete,
Failed,
}
#[derive(Debug, Clone)]
pub struct ProviderHealth {
pub provider: CdnProviderType,
pub status: EndpointStatus,
pub latency: f64,
pub uptime: f64, pub last_check: std::time::SystemTime,
}
pub struct SmartRouter {
providers: Arc<RwLock<Vec<Arc<dyn CdnProvider>>>>,
routing_cache: Arc<RwLock<HashMap<String, CdnEndpoint>>>,
}
impl SmartRouter {
pub fn new() -> Self {
SmartRouter {
providers: Arc::new(Mutex::new(Vec::new()))
routing_cache: Arc::new(Mutex::new(HashMap::new()))
}
}
pub async fn register_provider(&self, provider: Arc<dyn CdnProvider>) {
let mut providers = self.providers.write().await;
providers.push(provider);
}
pub async fn select_best_route(&self, region: &str) -> Result<CdnEndpoint> {
let cache_key: _ = format!("route:{}", region));
{
let cache: _ = self.routing_cache.read().await;
if let Some(endpoint) = cache.get(&cache_key) {
if endpoint.status == EndpointStatus::Healthy {
return Ok(endpoint.clone());
}
}
}
let providers: _ = self.providers.read().await;
let mut candidates = Vec::new();
for provider in providers.iter() {
match provider.route(region).await {
Ok(endpoint) => {
if endpoint.status == EndpointStatus::Healthy {
candidates.push(endpoint);
}
}
Err(_) => continue,
}
}
let best: _ = candidates
.into_iter()
.min_by(|a, b| {
let score_a: _ = a.clone();latency + (a.current_load * 100.0);
let score_b: _ = b.clone();latency + (b.current_load * 100.0);
score_a.partial_cmp(&score_b).unwrap_or(std::cmp::Ordering::Equal)
})
.context("No healthy endpoints available")?;
{
let mut cache = self.routing_cache.write().await;
cache.insert(cache_key, best.clone());
}
Ok(best)
}
pub async fn clear_cache(&self) {
let mut cache = self.routing_cache.write().await;
cache.clear();
}
}
#[derive(Debug)]
pub struct CdnOptimizer {
optimization_history: Arc<RwLock<Vec<OptimizationRecord>>>,
}
#[derive(Debug, Clone)]
struct OptimizationRecord {
timestamp: std::time::SystemTime,
config: HashMap<String, String>,
performance_delta: f64,
}
impl CdnOptimizer {
pub fn new() -> Self {
CdnOptimizer {
optimization_history: Arc::new(Mutex::new(Vec::new()))
}
}
pub async fn optimize(&self, mut config: HashMap<String, String>) -> Result<HashMap<String, String> {
let history: _ = self.optimization_history.read().await;
if let Some(tier) = config.get("tier") {
if tier == "enterprise" {
config.insert("cache_level".to_string(), "aggressive".to_string());
config.insert("compression".to_string(), "brotli".to_string());
config.insert("http_version".to_string(), "3".to_string());
}
}
config.insert("enable_http3".to_string(), "true".to_string());
config.insert("enable_0rtt".to_string(), "true".to_string());
drop(history);
let mut history = self.optimization_history.write().await;
history.push(OptimizationRecord {
timestamp: std::time::SystemTime::now(),
config: config.clone(),
performance_delta: 0.0, });
Ok(config)
}
pub async fn get_recommendations(&self) -> Result<Vec<String> {
let history: _ = self.optimization_history.read().await;
let mut recommendations = Vec::new();
if history.len() > 10 {
recommendations.push("Consider enabling edge compute for dynamic content".to_string());
recommendations.push("Implement image optimization at edge".to_string());
recommendations.push("Enable brotli compression for text assets".to_string());
}
Ok(recommendations)
}
}
#[cfg(test)]
mod tests {
struct MockProvider {
provider_type: CdnProviderType,
}
#[async_trait::async_trait]
impl CdnProvider for MockProvider {
async fn deploy(&self, _code: &[u8], _region: &str) -> Result<DeploymentResult> {
Ok(DeploymentResult {
deployment_id: "mock-deployment-123".to_string(),
endpoint_id: "mock-endpoint".to_string(),
status: DeploymentStatus::Complete,
deployment_url: Some("https://mock.example.com".to_string()),
estimated_propagation_time: 30,
})
}
async fn route(&self, _region: &str) -> Result<CdnEndpoint> {
Ok(CdnEndpoint {
id: "mock-endpoint".to_string(),
provider: self.provider_type,
region: "us-west".to_string(),
endpoint_url: "https://mock.example.com".to_string(),
latency: 45.0,
status: EndpointStatus::Healthy,
capacity: 10000,
current_load: 0.3,
})
}
async fn invalidate_cache(&self, _paths: &[&str]) -> Result<()> {
Ok(())
}
async fn health_check(&self) -> Result<ProviderHealth> {
Ok(ProviderHealth {
provider: self.provider_type,
status: EndpointStatus::Healthy,
latency: 45.0,
uptime: 99.99,
last_check: std::time::SystemTime::now(),
})
}
async fn update_config(&self, _config: &HashMap<String, String>) -> Result<()> {
Ok(())
}
}
#[tokio::test]
async fn test_smart_router_registration() {
let router: _ = SmartRouter::new();
let provider: _ = Arc::new(Mutex::new(MockProvider { provider_type: CdnProviderType::Cloudflare })),;
router.register_provider(provider).await;
let providers: _ = router.providers.read().await;
assert_eq!(providers.len(), 1);
}
#[tokio::test]
async fn test_smart_router_selection() {
let router: _ = SmartRouter::new();
let cloudflare: _ = Arc::new(Mutex::new(MockProvider { provider_type: CdnProviderType::Cloudflare })),;
let vercel: _ = Arc::new(Mutex::new(MockProvider { provider_type: CdnProviderType::Vercel })),;
router.register_provider(cloudflare).await;
router.register_provider(vercel).await;
let route: _ = router.select_best_route("us-west").await;
assert!(route.is_ok());
}
#[tokio::test]
async fn test_cdn_optimizer() {
let optimizer: _ = CdnOptimizer::new();
let mut config = HashMap::new();
config.insert("tier".to_string(), "enterprise".to_string());
let optimized: _ = optimizer.optimize(config).await;
assert!(optimized.is_ok());
let result: _ = optimized.unwrap();
assert_eq!(result.get("cache_level"), Some(&"aggressive".to_string());
assert_eq!(result.get("enable_http3"), Some(&"true".to_string());
}
}