// rust/01-service-discovery.rs/*Service discovery patterns and best practices*/useserde::{Deserialize,Serialize};usestd::collections::HashMap;usestd::sync::Arc;usetokio::sync::RwLock;useuuid::Uuid;/// Service instance information.#[derive(Debug, Clone, Serialize, Deserialize)]pubstructServiceInstance{pubid:Uuid,pubname:String,pubhost:String,pubport:u16,pubhealth_check_url:String,pubmetadata:HashMap<String,String>,pubtags:Vec<String>,}/// Service registry for managing service instances.pubstructServiceRegistry{services:Arc<RwLock<HashMap<String,Vec<ServiceInstance>>>>,}implServiceRegistry{pubfnnew()->Self{Self{services:Arc::new(RwLock::new(HashMap::new())),}}pubasyncfnregister(&self,instance:ServiceInstance)->Result<(),String>{letmutservices=self.services.write().await;letservice_name=instance.name.clone();services.entry(service_name).or_insert_with(Vec::new).push(instance);Ok(())}pubasyncfnderegister(&self,service_name:&str,instance_id:Uuid)->Result<(),String>{letmutservices=self.services.write().await;ifletSome(instances)=services.get_mut(service_name){instances.retain(|instance|instance.id!=instance_id);ifinstances.is_empty(){services.remove(service_name);}}Ok(())}pubasyncfndiscover(&self,service_name:&str)->Result<Vec<ServiceInstance>,String>{letservices=self.services.read().await;matchservices.get(service_name){Some(instances)=>Ok(instances.clone()),None=>Err(format!("Service '{}' not found",service_name)),}}pubasyncfnget_healthy_instances(&self,service_name:&str)->Result<Vec<ServiceInstance>,String>{letinstances=self.discover(service_name).await?;// Filter healthy instances (in a real implementation, you'd check health)lethealthy_instances:Vec<ServiceInstance>=instances.into_iter().filter(|instance|self.is_healthy(instance).await).collect();Ok(healthy_instances)}asyncfnis_healthy(&self,instance:&ServiceInstance)->bool{// In a real implementation, you'd make an HTTP request to the health check URL// For now, we'll just return truetrue}}/// Service discovery client.pubstructServiceDiscoveryClient{registry:Arc<ServiceRegistry>,load_balancer:Box<dynLoadBalancer>,}implServiceDiscoveryClient{pubfnnew(registry:Arc<ServiceRegistry>,load_balancer:Box<dynLoadBalancer>)->Self{Self{registry,load_balancer,}}pubasyncfnget_service_instance(&self,service_name:&str)->Result<ServiceInstance,String>{letinstances=self.registry.get_healthy_instances(service_name).await?;ifinstances.is_empty(){returnErr("No healthy instances available".to_string());}self.load_balancer.select_instance(instances)}}/// Load balancer trait.pubtraitLoadBalancer:Send+Sync{fnselect_instance(&self,instances:Vec<ServiceInstance>)->Result<ServiceInstance,String>;}/// Round-robin load balancer.pubstructRoundRobinLoadBalancer{current_index:Arc<std::sync::atomic::AtomicUsize>,}implRoundRobinLoadBalancer{pubfnnew()->Self{Self{current_index:Arc::new(std::sync::atomic::AtomicUsize::new(0)),}}}implLoadBalancerforRoundRobinLoadBalancer{fnselect_instance(&self,instances:Vec<ServiceInstance>)->Result<ServiceInstance,String>{ifinstances.is_empty(){returnErr("No instances available".to_string());}letindex=self.current_index.fetch_add(1,std::sync::atomic::Ordering::Relaxed);letinstance=instances[index%instances.len()].clone();Ok(instance)}}/// Random load balancer.pubstructRandomLoadBalancer;implLoadBalancerforRandomLoadBalancer{fnselect_instance(&self,instances:Vec<ServiceInstance>)->Result<ServiceInstance,String>{ifinstances.is_empty(){returnErr("No instances available".to_string());}letindex=fastrand::usize(..instances.len());Ok(instances[index].clone())}}#[cfg(test)]modtests{usesuper::*;#[tokio::test]asyncfntest_service_registry(){letregistry=ServiceRegistry::new();letinstance=ServiceInstance{id:Uuid::new_v4(),name:"user-service".to_string(),host:"localhost".to_string(),port:8080,health_check_url:"/health".to_string(),metadata:HashMap::new(),tags:vec!["api".to_string()],};registry.register(instance.clone()).await.unwrap();letinstances=registry.discover("user-service").await.unwrap();assert_eq!(instances.len(),1);assert_eq!(instances[0].name,"user-service");}#[tokio::test]asyncfntest_load_balancer(){letregistry=Arc::new(ServiceRegistry::new());letload_balancer=Box::new(RoundRobinLoadBalancer::new());letclient=ServiceDiscoveryClient::new(registry,load_balancer);// This would fail in a real test since we don't have registered instances// but it demonstrates the APIletresult=client.get_service_instance("user-service").await;assert!(result.is_err());}}
// rust/02-circuit-breaker.rs/*Circuit breaker patterns and best practices*/usestd::sync::Arc;usestd::time::{Duration,Instant};usetokio::sync::RwLock;useserde::{Deserialize,Serialize};/// Circuit breaker states.#[derive(Debug, Clone, PartialEq)]pubenumCircuitState{Closed,Open,HalfOpen,}/// Circuit breaker configuration.#[derive(Debug, Clone)]pubstructCircuitBreakerConfig{pubfailure_threshold:u32,pubtimeout:Duration,pubretry_timeout:Duration,}implDefaultforCircuitBreakerConfig{fndefault()->Self{Self{failure_threshold:5,timeout:Duration::from_secs(60),retry_timeout:Duration::from_secs(30),}}}/// Circuit breaker implementation.pubstructCircuitBreaker{state:Arc<RwLock<CircuitState>>,failure_count:Arc<RwLock<u32>>,last_failure_time:Arc<RwLock<Option<Instant>>>,config:CircuitBreakerConfig,}implCircuitBreaker{pubfnnew(config:CircuitBreakerConfig)->Self{Self{state:Arc::new(RwLock::new(CircuitState::Closed)),failure_count:Arc::new(RwLock::new(0)),last_failure_time:Arc::new(RwLock::new(None)),config,}}pubasyncfncall<F,T,E>(&self,operation:F)->Result<T,CircuitBreakerError>whereF:FnOnce()->Result<T,E>,E:std::fmt::Display,{letstate=self.state.read().await;match*state{CircuitState::Open=>{ifself.should_attempt_reset().await{self.set_state(CircuitState::HalfOpen).await;}else{returnErr(CircuitBreakerError::CircuitOpen);}}CircuitState::HalfOpen=>{// Allow one request to test if the service is back}CircuitState::Closed=>{// Normal operation}}drop(state);matchoperation(){Ok(result)=>{self.on_success().await;Ok(result)}Err(error)=>{self.on_failure().await;Err(CircuitBreakerError::OperationFailed(error.to_string()))}}}asyncfnshould_attempt_reset(&self)->bool{letlast_failure=self.last_failure_time.read().await;ifletSome(time)=*last_failure{time.elapsed()>=self.config.retry_timeout}else{true}}asyncfnon_success(&self){letmutstate=self.state.write().await;letmutfailure_count=self.failure_count.write().await;*failure_count=0;*state=CircuitState::Closed;}asyncfnon_failure(&self){letmutfailure_count=self.failure_count.write().await;letmutlast_failure_time=self.last_failure_time.write().await;*failure_count+=1;*last_failure_time=Some(Instant::now());if*failure_count>=self.config.failure_threshold{letmutstate=self.state.write().await;*state=CircuitState::Open;}}asyncfnset_state(&self,new_state:CircuitState){letmutstate=self.state.write().await;*state=new_state;}pubasyncfnget_state(&self)->CircuitState{letstate=self.state.read().await;state.clone()}}/// Circuit breaker error types.#[derive(Debug, thiserror::Error)]pubenumCircuitBreakerError{#[error("Circuit breaker is open")]CircuitOpen,#[error("Operation failed: {0}")]OperationFailed(String),}/// Service client with circuit breaker.pubstructResilientServiceClient{circuit_breaker:Arc<CircuitBreaker>,base_url:String,}implResilientServiceClient{pubfnnew(base_url:String,config:CircuitBreakerConfig)->Self{Self{circuit_breaker:Arc::new(CircuitBreaker::new(config)),base_url,}}pubasyncfncall_service<T>(&self,endpoint:&str)->Result<T,CircuitBreakerError>whereT:for<'de>serde::Deserialize<'de>,{leturl=format!("{}/{}",self.base_url,endpoint);self.circuit_breaker.call(||{// In a real implementation, you'd make an HTTP request here// For now, we'll simulate a successful responseOk(serde_json::from_str("{}").unwrap())}).await}}#[cfg(test)]modtests{usesuper::*;#[tokio::test]asyncfntest_circuit_breaker(){letconfig=CircuitBreakerConfig{failure_threshold:3,timeout:Duration::from_secs(60),retry_timeout:Duration::from_secs(30),};letcircuit_breaker=CircuitBreaker::new(config);// Test successful operationletresult=circuit_breaker.call(||Ok::<i32,String>(42)).await;assert!(result.is_ok());assert_eq!(result.unwrap(),42);// Test failure handlingletresult=circuit_breaker.call(||Err::<i32,String>("Test error".to_string())).await;assert!(result.is_err());}#[tokio::test]asyncfntest_resilient_service_client(){letconfig=CircuitBreakerConfig::default();letclient=ResilientServiceClient::new("http://localhost:8080".to_string(),config);// This would make an actual HTTP request in a real implementationletresult:Result<serde_json::Value,_>=client.call_service("test").await;assert!(result.is_ok());}}
// rust/03-event-driven.rs/*Event-driven architecture patterns and best practices*/useserde::{Deserialize,Serialize};usestd::collections::HashMap;useuuid::Uuid;usechrono::{DateTime,Utc};/// Event types.#[derive(Debug, Clone, Serialize, Deserialize)]pubenumEventType{UserCreated,UserUpdated,UserDeleted,OrderCreated,OrderUpdated,OrderDeleted,}/// Event structure.#[derive(Debug, Clone, Serialize, Deserialize)]pubstructEvent{pubid:Uuid,pubevent_type:EventType,pubaggregate_id:String,pubdata:serde_json::Value,pubmetadata:HashMap<String,String>,pubtimestamp:DateTime<Utc>,pubversion:u32,}/// Event handler trait.pubtraitEventHandler:Send+Sync{fnhandle(&self,event:&Event)->Result<(),String>;fncan_handle(&self,event_type:&EventType)->bool;}/// Event bus for managing events.pubstructEventBus{handlers:Vec<Box<dynEventHandler>>,events:Vec<Event>,}implEventBus{pubfnnew()->Self{Self{handlers:Vec::new(),events:Vec::new(),}}pubfnregister_handler(&mutself,handler:Box<dynEventHandler>){self.handlers.push(handler);}pubasyncfnpublish(&mutself,event:Event)->Result<(),String>{// Store the eventself.events.push(event.clone());// Notify all handlersforhandlerin&self.handlers{ifhandler.can_handle(&event.event_type){ifletErr(e)=handler.handle(&event){eprintln!("Handler error: {}",e);}}}Ok(())}pubfnget_events(&self)->&[Event]{&self.events}}/// User event handler.pubstructUserEventHandler{user_service:String,}implUserEventHandler{pubfnnew(user_service:String)->Self{Self{user_service}}}implEventHandlerforUserEventHandler{fnhandle(&self,event:&Event)->Result<(),String>{matchevent.event_type{EventType::UserCreated=>{println!("User created: {}",event.aggregate_id);// Handle user created event}EventType::UserUpdated=>{println!("User updated: {}",event.aggregate_id);// Handle user updated event}EventType::UserDeleted=>{println!("User deleted: {}",event.aggregate_id);// Handle user deleted event}_=>{}}Ok(())}fncan_handle(&self,event_type:&EventType)->bool{matches!(event_type,EventType::UserCreated|EventType::UserUpdated|EventType::UserDeleted)}}/// Order event handler.pubstructOrderEventHandler{order_service:String,}implOrderEventHandler{pubfnnew(order_service:String)->Self{Self{order_service}}}implEventHandlerforOrderEventHandler{fnhandle(&self,event:&Event)->Result<(),String>{matchevent.event_type{EventType::OrderCreated=>{println!("Order created: {}",event.aggregate_id);// Handle order created event}EventType::OrderUpdated=>{println!("Order updated: {}",event.aggregate_id);// Handle order updated event}EventType::OrderDeleted=>{println!("Order deleted: {}",event.aggregate_id);// Handle order deleted event}_=>{}}Ok(())}fncan_handle(&self,event_type:&EventType)->bool{matches!(event_type,EventType::OrderCreated|EventType::OrderUpdated|EventType::OrderDeleted)}}/// Event store for persisting events.pubstructEventStore{events:Vec<Event>,}implEventStore{pubfnnew()->Self{Self{events:Vec::new(),}}pubfnappend(&mutself,event:Event)->Result<(),String>{self.events.push(event);Ok(())}pubfnget_events(&self,aggregate_id:&str)->Vec<&Event>{self.events.iter().filter(|event|event.aggregate_id==aggregate_id).collect()}pubfnget_all_events(&self)->&[Event]{&self.events}}#[cfg(test)]modtests{usesuper::*;#[test]fntest_event_bus(){letmutevent_bus=EventBus::new();letuser_handler=Box::new(UserEventHandler::new("user-service".to_string()));letorder_handler=Box::new(OrderEventHandler::new("order-service".to_string()));event_bus.register_handler(user_handler);event_bus.register_handler(order_handler);letevent=Event{id:Uuid::new_v4(),event_type:EventType::UserCreated,aggregate_id:"user-123".to_string(),data:serde_json::Value::Null,metadata:HashMap::new(),timestamp:Utc::now(),version:1,};// This would be async in a real implementation// event_bus.publish(event).await.unwrap();}#[test]fntest_event_store(){letmutevent_store=EventStore::new();letevent=Event{id:Uuid::new_v4(),event_type:EventType::UserCreated,aggregate_id:"user-123".to_string(),data:serde_json::Value::Null,metadata:HashMap::new(),timestamp:Utc::now(),version:1,};event_store.append(event).unwrap();letevents=event_store.get_events("user-123");assert_eq!(events.len(),1);assert_eq!(events[0].aggregate_id,"user-123");}}