// rust/01-blue-green-deployment.rs/*Blue-green deployment patterns and best practices*/usestd::collections::HashMap;useserde::{Deserialize,Serialize};usestd::time::{Duration,Instant};/// Blue-green deployment manager.pubstructBlueGreenDeployment{blue_environment:Environment,green_environment:Environment,active_environment:EnvironmentType,deployment_config:DeploymentConfig,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructEnvironment{pubname:String,pubversion:String,pubstatus:EnvironmentStatus,pubhealth_check_url:String,pubload_balancer_weight:u32,pubinstances:Vec<Instance>,}#[derive(Debug, Clone, Serialize, Deserialize)]pubenumEnvironmentStatus{Healthy,Unhealthy,Deploying,Deployed,Failed,}#[derive(Debug, Clone, Serialize, Deserialize)]pubenumEnvironmentType{Blue,Green,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructInstance{pubid:String,pubstatus:InstanceStatus,pubhealth_check_url:String,pubload_balancer_weight:u32,}#[derive(Debug, Clone, Serialize, Deserialize)]pubenumInstanceStatus{Healthy,Unhealthy,Starting,Stopping,Stopped,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructDeploymentConfig{pubhealth_check_timeout:Duration,pubhealth_check_interval:Duration,pubmax_health_check_attempts:u32,pubrollback_timeout:Duration,pubload_balancer_switch_delay:Duration,}implBlueGreenDeployment{pubfnnew(config:DeploymentConfig)->Self{Self{blue_environment:Environment{name:"blue".to_string(),version:"1.0.0".to_string(),status:EnvironmentStatus::Healthy,health_check_url:"http://blue.example.com/health".to_string(),load_balancer_weight:100,instances:Vec::new(),},green_environment:Environment{name:"green".to_string(),version:"1.0.0".to_string(),status:EnvironmentStatus::Healthy,health_check_url:"http://green.example.com/health".to_string(),load_balancer_weight:0,instances:Vec::new(),},active_environment:EnvironmentType::Blue,deployment_config:config,}}/// Deploy a new version using blue-green deployment.pubasyncfndeploy(&mutself,new_version:String)->Result<DeploymentResult,String>{letstart_time=Instant::now();// Determine which environment to deploy tolettarget_environment=matchself.active_environment{EnvironmentType::Blue=>&mutself.green_environment,EnvironmentType::Green=>&mutself.blue_environment,};// Deploy to inactive environmenttarget_environment.status=EnvironmentStatus::Deploying;target_environment.version=new_version.clone();// Deploy instancesself.deploy_instances(target_environment).await?;// Wait for health checksself.wait_for_health_checks(target_environment).await?;// Switch traffic to new environmentself.switch_traffic().await?;// Update active environmentself.active_environment=matchself.active_environment{EnvironmentType::Blue=>EnvironmentType::Green,EnvironmentType::Green=>EnvironmentType::Blue,};letduration=start_time.elapsed();Ok(DeploymentResult{success:true,duration,new_version,active_environment:self.active_environment.clone(),})}/// Deploy instances to an environment.asyncfndeploy_instances(&self,environment:&mutEnvironment)->Result<(),String>{// In a real implementation, you would deploy instances using// Kubernetes, Docker Swarm, or other orchestration platformprintln!("Deploying instances to {} environment",environment.name);// Simulate deploymenttokio::time::sleep(Duration::from_secs(5)).await;// Create instancesenvironment.instances=vec![Instance{id:"instance-1".to_string(),status:InstanceStatus::Starting,health_check_url:format!("{}/health",environment.health_check_url),load_balancer_weight:50,},Instance{id:"instance-2".to_string(),status:InstanceStatus::Starting,health_check_url:format!("{}/health",environment.health_check_url),load_balancer_weight:50,},];Ok(())}/// Wait for health checks to pass.asyncfnwait_for_health_checks(&self,environment:&mutEnvironment)->Result<(),String>{letmutattempts=0;whileattempts<self.deployment_config.max_health_check_attempts{// Check health of all instancesletmutall_healthy=true;forinstancein&mutenvironment.instances{ifself.check_instance_health(instance).await?{instance.status=InstanceStatus::Healthy;}else{instance.status=InstanceStatus::Unhealthy;all_healthy=false;}}ifall_healthy{environment.status=EnvironmentStatus::Healthy;returnOk(());}attempts+=1;tokio::time::sleep(self.deployment_config.health_check_interval).await;}environment.status=EnvironmentStatus::Failed;Err("Health checks failed".to_string())}/// Check health of a single instance.asyncfncheck_instance_health(&self,instance:&Instance)->Result<bool,String>{// In a real implementation, you would make an HTTP request// to the health check URLprintln!("Checking health of instance {}",instance.id);// Simulate health checktokio::time::sleep(Duration::from_millis(100)).await;// For this example, assume all instances are healthyOk(true)}/// Switch traffic to the new environment.asyncfnswitch_traffic(&mutself)->Result<(),String>{// In a real implementation, you would update load balancer// configuration to route traffic to the new environmentlet(blue_weight,green_weight)=matchself.active_environment{EnvironmentType::Blue=>(100,0),EnvironmentType::Green=>(0,100),};self.blue_environment.load_balancer_weight=blue_weight;self.green_environment.load_balancer_weight=green_weight;// Wait for load balancer to switchtokio::time::sleep(self.deployment_config.load_balancer_switch_delay).await;Ok(())}/// Rollback to the previous environment.pubasyncfnrollback(&mutself)->Result<DeploymentResult,String>{letstart_time=Instant::now();// Switch back to the previous environmentself.active_environment=matchself.active_environment{EnvironmentType::Blue=>EnvironmentType::Green,EnvironmentType::Green=>EnvironmentType::Blue,};// Switch traffic backself.switch_traffic().await?;letduration=start_time.elapsed();Ok(DeploymentResult{success:true,duration,new_version:"rollback".to_string(),active_environment:self.active_environment.clone(),})}/// Get deployment status.pubfnget_status(&self)->DeploymentStatus{DeploymentStatus{active_environment:self.active_environment.clone(),blue_environment:self.blue_environment.clone(),green_environment:self.green_environment.clone(),}}}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructDeploymentResult{pubsuccess:bool,pubduration:Duration,pubnew_version:String,pubactive_environment:EnvironmentType,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructDeploymentStatus{pubactive_environment:EnvironmentType,pubblue_environment:Environment,pubgreen_environment:Environment,}#[cfg(test)]modtests{usesuper::*;#[tokio::test]asyncfntest_blue_green_deployment(){letconfig=DeploymentConfig{health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,rollback_timeout:Duration::from_secs(60),load_balancer_switch_delay:Duration::from_secs(10),};letmutdeployment=BlueGreenDeployment::new(config);letresult=deployment.deploy("2.0.0".to_string()).await;assert!(result.is_ok());assert!(result.unwrap().success);}#[tokio::test]asyncfntest_rollback(){letconfig=DeploymentConfig{health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,rollback_timeout:Duration::from_secs(60),load_balancer_switch_delay:Duration::from_secs(10),};letmutdeployment=BlueGreenDeployment::new(config);letresult=deployment.rollback().await;assert!(result.is_ok());assert!(result.unwrap().success);}}
// rust/02-canary-deployment.rs/*Canary deployment patterns and best practices*/usestd::collections::HashMap;useserde::{Deserialize,Serialize};usestd::time::{Duration,Instant};/// Canary deployment manager.pubstructCanaryDeployment{stable_environment:Environment,canary_environment:Environment,canary_percentage:u32,deployment_config:DeploymentConfig,metrics:CanaryMetrics,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructCanaryMetrics{puberror_rate:f64,pubresponse_time:Duration,pubthroughput:f64,pubcpu_usage:f64,pubmemory_usage:f64,}implCanaryDeployment{pubfnnew(config:DeploymentConfig)->Self{Self{stable_environment:Environment{name:"stable".to_string(),version:"1.0.0".to_string(),status:EnvironmentStatus::Healthy,health_check_url:"http://stable.example.com/health".to_string(),load_balancer_weight:100,instances:Vec::new(),},canary_environment:Environment{name:"canary".to_string(),version:"1.0.0".to_string(),status:EnvironmentStatus::Healthy,health_check_url:"http://canary.example.com/health".to_string(),load_balancer_weight:0,instances:Vec::new(),},canary_percentage:0,deployment_config:config,metrics:CanaryMetrics{error_rate:0.0,response_time:Duration::from_millis(100),throughput:1000.0,cpu_usage:50.0,memory_usage:60.0,},}}/// Deploy a new version using canary deployment.pubasyncfndeploy(&mutself,new_version:String,initial_percentage:u32)->Result<DeploymentResult,String>{letstart_time=Instant::now();// Deploy to canary environmentself.canary_environment.status=EnvironmentStatus::Deploying;self.canary_environment.version=new_version.clone();// Deploy instancesself.deploy_instances(&mutself.canary_environment).await?;// Wait for health checksself.wait_for_health_checks(&mutself.canary_environment).await?;// Start with initial canary percentageself.canary_percentage=initial_percentage;self.update_load_balancer_weights().await?;// Monitor canary metricsself.monitor_canary_metrics().await?;letduration=start_time.elapsed();Ok(DeploymentResult{success:true,duration,new_version,active_environment:EnvironmentType::Blue,// Not applicable for canary})}/// Deploy instances to an environment.asyncfndeploy_instances(&self,environment:&mutEnvironment)->Result<(),String>{// In a real implementation, you would deploy instances using// Kubernetes, Docker Swarm, or other orchestration platformprintln!("Deploying instances to {} environment",environment.name);// Simulate deploymenttokio::time::sleep(Duration::from_secs(5)).await;// Create instancesenvironment.instances=vec![Instance{id:"instance-1".to_string(),status:InstanceStatus::Starting,health_check_url:format!("{}/health",environment.health_check_url),load_balancer_weight:50,},];Ok(())}/// Wait for health checks to pass.asyncfnwait_for_health_checks(&self,environment:&mutEnvironment)->Result<(),String>{letmutattempts=0;whileattempts<self.deployment_config.max_health_check_attempts{// Check health of all instancesletmutall_healthy=true;forinstancein&mutenvironment.instances{ifself.check_instance_health(instance).await?{instance.status=InstanceStatus::Healthy;}else{instance.status=InstanceStatus::Unhealthy;all_healthy=false;}}ifall_healthy{environment.status=EnvironmentStatus::Healthy;returnOk(());}attempts+=1;tokio::time::sleep(self.deployment_config.health_check_interval).await;}environment.status=EnvironmentStatus::Failed;Err("Health checks failed".to_string())}/// Check health of a single instance.asyncfncheck_instance_health(&self,instance:&Instance)->Result<bool,String>{// In a real implementation, you would make an HTTP request// to the health check URLprintln!("Checking health of instance {}",instance.id);// Simulate health checktokio::time::sleep(Duration::from_millis(100)).await;// For this example, assume all instances are healthyOk(true)}/// Update load balancer weights based on canary percentage.asyncfnupdate_load_balancer_weights(&mutself)->Result<(),String>{letstable_weight=100-self.canary_percentage;letcanary_weight=self.canary_percentage;self.stable_environment.load_balancer_weight=stable_weight;self.canary_environment.load_balancer_weight=canary_weight;println!("Updated load balancer weights: stable={}%, canary={}%",stable_weight,canary_weight);Ok(())}/// Monitor canary metrics and make decisions.asyncfnmonitor_canary_metrics(&mutself)->Result<(),String>{// In a real implementation, you would collect metrics from// monitoring systems like Prometheus, DataDog, etc.// Simulate metric collectionself.metrics.error_rate=0.01;// 1% error rateself.metrics.response_time=Duration::from_millis(150);self.metrics.throughput=1200.0;self.metrics.cpu_usage=55.0;self.metrics.memory_usage=65.0;// Check if metrics are within acceptable rangesifself.metrics.error_rate>0.05{// 5% error rate thresholdreturnErr("Canary deployment failed: error rate too high".to_string());}ifself.metrics.response_time>Duration::from_millis(500){returnErr("Canary deployment failed: response time too high".to_string());}ifself.metrics.cpu_usage>80.0{returnErr("Canary deployment failed: CPU usage too high".to_string());}ifself.metrics.memory_usage>90.0{returnErr("Canary deployment failed: memory usage too high".to_string());}Ok(())}/// Increase canary percentage.pubasyncfnincrease_canary_percentage(&mutself,percentage:u32)->Result<(),String>{self.canary_percentage=(self.canary_percentage+percentage).min(100);self.update_load_balancer_weights().await?;// Monitor metrics after increaseself.monitor_canary_metrics().await?;Ok(())}/// Promote canary to stable.pubasyncfnpromote_canary(&mutself)->Result<(),String>{// Switch all traffic to canaryself.canary_percentage=100;self.update_load_balancer_weights().await?;// Wait for traffic to stabilizetokio::time::sleep(Duration::from_secs(30)).await;// Update stable environmentself.stable_environment.version=self.canary_environment.version.clone();self.stable_environment.instances=self.canary_environment.instances.clone();// Reset canaryself.canary_percentage=0;self.update_load_balancer_weights().await?;Ok(())}/// Rollback canary deployment.pubasyncfnrollback_canary(&mutself)->Result<(),String>{// Set canary percentage to 0self.canary_percentage=0;self.update_load_balancer_weights().await?;// Stop canary instancesforinstancein&mutself.canary_environment.instances{instance.status=InstanceStatus::Stopped;}Ok(())}/// Get canary metrics.pubfnget_metrics(&self)->&CanaryMetrics{&self.metrics}/// Get canary status.pubfnget_status(&self)->CanaryStatus{CanaryStatus{canary_percentage:self.canary_percentage,stable_environment:self.stable_environment.clone(),canary_environment:self.canary_environment.clone(),metrics:self.metrics.clone(),}}}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructCanaryStatus{pubcanary_percentage:u32,pubstable_environment:Environment,pubcanary_environment:Environment,pubmetrics:CanaryMetrics,}#[cfg(test)]modtests{usesuper::*;#[tokio::test]asyncfntest_canary_deployment(){letconfig=DeploymentConfig{health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,rollback_timeout:Duration::from_secs(60),load_balancer_switch_delay:Duration::from_secs(10),};letmutdeployment=CanaryDeployment::new(config);letresult=deployment.deploy("2.0.0".to_string(),10).await;assert!(result.is_ok());assert!(result.unwrap().success);}#[tokio::test]asyncfntest_increase_canary_percentage(){letconfig=DeploymentConfig{health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,rollback_timeout:Duration::from_secs(60),load_balancer_switch_delay:Duration::from_secs(10),};letmutdeployment=CanaryDeployment::new(config);deployment.deploy("2.0.0".to_string(),10).await.unwrap();letresult=deployment.increase_canary_percentage(20).await;assert!(result.is_ok());assert_eq!(deployment.canary_percentage,30);}#[tokio::test]asyncfntest_promote_canary(){letconfig=DeploymentConfig{health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,rollback_timeout:Duration::from_secs(60),load_balancer_switch_delay:Duration::from_secs(10),};letmutdeployment=CanaryDeployment::new(config);deployment.deploy("2.0.0".to_string(),10).await.unwrap();letresult=deployment.promote_canary().await;assert!(result.is_ok());assert_eq!(deployment.canary_percentage,0);}}
// rust/03-rolling-updates.rs/*Rolling update patterns and best practices*/usestd::collections::HashMap;useserde::{Deserialize,Serialize};usestd::time::{Duration,Instant};/// Rolling update manager.pubstructRollingUpdateManager{instances:Vec<Instance>,new_version:String,update_config:UpdateConfig,update_status:UpdateStatus,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructUpdateConfig{pubmax_unavailable:u32,pubmax_surge:u32,pubupdate_timeout:Duration,pubhealth_check_timeout:Duration,pubhealth_check_interval:Duration,pubmax_health_check_attempts:u32,}#[derive(Debug, Clone, Serialize, Deserialize)]pubenumUpdateStatus{NotStarted,InProgress,Completed,Failed,RollingBack,}implRollingUpdateManager{pubfnnew(instances:Vec<Instance>,new_version:String,config:UpdateConfig)->Self{Self{instances,new_version,update_config:config,update_status:UpdateStatus::NotStarted,}}/// Start rolling update.pubasyncfnstart_update(&mutself)->Result<UpdateResult,String>{letstart_time=Instant::now();self.update_status=UpdateStatus::InProgress;// Calculate update strategyletstrategy=self.calculate_update_strategy()?;// Update instances in batchesforbatchinstrategy.batches{self.update_batch(batch).await?;}self.update_status=UpdateStatus::Completed;letduration=start_time.elapsed();Ok(UpdateResult{success:true,duration,updated_instances:self.instances.len(),failed_instances:0,})}/// Calculate update strategy.fncalculate_update_strategy(&self)->Result<UpdateStrategy,String>{lettotal_instances=self.instances.len()asu32;letmax_unavailable=self.update_config.max_unavailable;letmax_surge=self.update_config.max_surge;// Calculate batch sizeletbatch_size=ifmax_unavailable>0{(total_instances-max_unavailable).min(max_surge)}else{max_surge};ifbatch_size==0{returnErr("Invalid update configuration".to_string());}// Create batchesletmutbatches=Vec::new();letmutremaining_instances=total_instances;whileremaining_instances>0{letcurrent_batch_size=batch_size.min(remaining_instances);batches.push(current_batch_size);remaining_instances-=current_batch_size;}Ok(UpdateStrategy{batches})}/// Update a batch of instances.asyncfnupdate_batch(&mutself,batch_size:u32)->Result<(),String>{letmutupdated_count=0;forinstancein&mutself.instances{ifupdated_count>=batch_size{break;}ifinstance.status==InstanceStatus::Healthy{// Update instanceself.update_instance(instance).await?;updated_count+=1;}}// Wait for batch to be healthyself.wait_for_batch_health().await?;Ok(())}/// Update a single instance.asyncfnupdate_instance(&self,instance:&mutInstance)->Result<(),String>{println!("Updating instance {}",instance.id);// In a real implementation, you would:// 1. Deploy new version to instance// 2. Update load balancer configuration// 3. Wait for instance to be ready// Simulate updateinstance.status=InstanceStatus::Starting;tokio::time::sleep(Duration::from_secs(2)).await;// Check healthifself.check_instance_health(instance).await?{instance.status=InstanceStatus::Healthy;}else{instance.status=InstanceStatus::Unhealthy;returnErr("Instance health check failed".to_string());}Ok(())}/// Check health of a single instance.asyncfncheck_instance_health(&self,instance:&Instance)->Result<bool,String>{// In a real implementation, you would make an HTTP request// to the health check URLprintln!("Checking health of instance {}",instance.id);// Simulate health checktokio::time::sleep(Duration::from_millis(100)).await;// For this example, assume all instances are healthyOk(true)}/// Wait for batch to be healthy.asyncfnwait_for_batch_health(&self)->Result<(),String>{letmutattempts=0;whileattempts<self.update_config.max_health_check_attempts{letmutall_healthy=true;forinstancein&self.instances{ifinstance.status==InstanceStatus::Starting{if!self.check_instance_health(instance).await?{all_healthy=false;break;}}}ifall_healthy{returnOk(());}attempts+=1;tokio::time::sleep(self.update_config.health_check_interval).await;}Err("Batch health check failed".to_string())}/// Rollback update.pubasyncfnrollback(&mutself)->Result<UpdateResult,String>{letstart_time=Instant::now();self.update_status=UpdateStatus::RollingBack;// Rollback all instancesforinstancein&mutself.instances{ifinstance.status==InstanceStatus::Healthy{self.rollback_instance(instance).await?;}}self.update_status=UpdateStatus::Completed;letduration=start_time.elapsed();Ok(UpdateResult{success:true,duration,updated_instances:0,failed_instances:0,})}/// Rollback a single instance.asyncfnrollback_instance(&self,instance:&mutInstance)->Result<(),String>{println!("Rolling back instance {}",instance.id);// In a real implementation, you would:// 1. Deploy previous version to instance// 2. Update load balancer configuration// 3. Wait for instance to be ready// Simulate rollbackinstance.status=InstanceStatus::Starting;tokio::time::sleep(Duration::from_secs(2)).await;// Check healthifself.check_instance_health(instance).await?{instance.status=InstanceStatus::Healthy;}else{instance.status=InstanceStatus::Unhealthy;returnErr("Instance rollback failed".to_string());}Ok(())}/// Get update status.pubfnget_status(&self)->&UpdateStatus{&self.update_status}/// Get instance status.pubfnget_instance_status(&self)->Vec<&Instance>{self.instances.iter().collect()}}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructUpdateStrategy{pubbatches:Vec<u32>,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructUpdateResult{pubsuccess:bool,pubduration:Duration,pubupdated_instances:usize,pubfailed_instances:usize,}#[cfg(test)]modtests{usesuper::*;#[tokio::test]asyncfntest_rolling_update(){letinstances=vec![Instance{id:"instance-1".to_string(),status:InstanceStatus::Healthy,health_check_url:"http://instance-1.example.com/health".to_string(),load_balancer_weight:50,},Instance{id:"instance-2".to_string(),status:InstanceStatus::Healthy,health_check_url:"http://instance-2.example.com/health".to_string(),load_balancer_weight:50,},];letconfig=UpdateConfig{max_unavailable:1,max_surge:1,update_timeout:Duration::from_secs(300),health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,};letmutmanager=RollingUpdateManager::new(instances,"2.0.0".to_string(),config);letresult=manager.start_update().await;assert!(result.is_ok());assert!(result.unwrap().success);}#[tokio::test]asyncfntest_rollback(){letinstances=vec![Instance{id:"instance-1".to_string(),status:InstanceStatus::Healthy,health_check_url:"http://instance-1.example.com/health".to_string(),load_balancer_weight:50,},];letconfig=UpdateConfig{max_unavailable:1,max_surge:1,update_timeout:Duration::from_secs(300),health_check_timeout:Duration::from_secs(30),health_check_interval:Duration::from_secs(5),max_health_check_attempts:6,};letmutmanager=RollingUpdateManager::new(instances,"2.0.0".to_string(),config);letresult=manager.rollback().await;assert!(result.is_ok());assert!(result.unwrap().success);}}