Cross Platform Universal Applications – DEV Community


As a junior computer science student, I have always been intrigued by the challenge of building applications that work seamlessly across different platforms. During my exploration of modern development practices, I discovered that creating truly universal web applications requires more than just writing portable code – it demands a deep understanding of deployment strategies, environment management, and platform-specific optimizations.

In my ten years of programming learning experience, I have witnessed the evolution from platform-specific development to universal application frameworks. The dream of “write once, run everywhere” has driven countless innovations in software development, from Java’s virtual machine to modern containerization technologies.

Modern web frameworks have brought us closer to this ideal than ever before. By leveraging platform-agnostic technologies and standardized deployment practices, we can build applications that deliver consistent experiences across diverse environments.

use hyperlane::*;
use hyperlane_macros::*;
use std::collections::HashMap;
use serde::Deserialize, Serialize;

// Cross-platform configuration management
#[derive(Clone, Debug)]
struct PlatformConfig 
    platform_info: PlatformInfo,
    deployment_config: DeploymentConfig,
    feature_flags: HashMap<String, bool>,
    environment_variables: HashMap<String, String>,


#[derive(Clone, Debug)]
struct PlatformInfo 
    os_type: OperatingSystem,
    architecture: Architecture,
    runtime_version: String,
    available_memory: u64,
    cpu_cores: u32,


#[derive(Clone, Debug)]
enum OperatingSystem 
    Linux,
    Windows,
    MacOS,
    FreeBSD,
    Unknown(String),


#[derive(Clone, Debug)]
enum Architecture 
    X86_64,
    ARM64,
    X86,
    ARM,
    Unknown(String),


#[derive(Clone, Debug)]
struct DeploymentConfig 
    container_runtime: Option<String>,
    service_port: u16,
    health_check_endpoint: String,
    log_level: LogLevel,
    max_connections: usize,
    request_timeout: std::time::Duration,


#[derive(Clone, Debug)]
enum LogLevel 
    Error,
    Warn,
    Info,
    Debug,
    Trace,


impl PlatformConfig {
    fn detect_platform() -> Self 
        let platform_info = Self::detect_platform_info();
        let deployment_config = Self::create_deployment_config(&platform_info);
        let feature_flags = Self::load_feature_flags(&platform_info);
        let environment_variables = Self::load_environment_variables();

        Self 
            platform_info,
            deployment_config,
            feature_flags,
            environment_variables,
        
    

    fn detect_platform_info() -> PlatformInfo 
        let os_type = match std::env::consts::OS 
            "linux" => OperatingSystem::Linux,
            "windows" => OperatingSystem::Windows,
            "macos" => OperatingSystem::MacOS,
            "freebsd" => OperatingSystem::FreeBSD,
            other => OperatingSystem::Unknown(other.to_string()),
        ;

        let architecture = match std::env::consts::ARCH 
            "x86_64" => Architecture::X86_64,
            "aarch64" => Architecture::ARM64,
            "x86" => Architecture::X86,
            "arm" => Architecture::ARM,
            other => Architecture::Unknown(other.to_string()),
        ;

        PlatformInfo 
            os_type,
            architecture,
            runtime_version: env!("CARGO_PKG_VERSION").to_string(),
            available_memory: Self::get_available_memory(),
            cpu_cores: num_cpus::get() as u32,
        
    

    fn get_available_memory() -> u64 {
        // Simplified memory detection
        match std::env::var("MEMORY_LIMIT") {
            Ok(limit) => limit.parse().unwrap_or(1024 * 1024 * 1024), // Default 1GB
            Err(_) => {
                // Try to detect system memory
                #[cfg(target_os = "linux")]
                {
                    if let Ok(meminfo) = std::fs::read_to_string("/proc/meminfo") {
                        for line in meminfo.lines() 
                            if line.starts_with("MemTotal:") 
                                if let Some(kb_str) = line.split_whitespace().nth(1) 
                                    if let Ok(kb) = kb_str.parse::<u64>() 
                                        return kb * 1024; // Convert KB to bytes
                                    
                                
                            
                        
                    }
                }

                // Default fallback
                2 * 1024 * 1024 * 1024 // 2GB
            }
        }
    }

    fn create_deployment_config(platform_info: &PlatformInfo) -> DeploymentConfig p

    fn load_feature_flags(platform_info: &PlatformInfo) -> HashMap<String, bool> 
        let mut flags = HashMap::new();

        // Platform-specific feature flags
        match platform_info.os_type 
            OperatingSystem::Linux => 
                flags.insert("epoll_support".to_string(), true);
                flags.insert("sendfile_support".to_string(), true);
            
            OperatingSystem::Windows => 
                flags.insert("iocp_support".to_string(), true);
                flags.insert("windows_service".to_string(), true);
            
            OperatingSystem::MacOS => 
                flags.insert("kqueue_support".to_string(), true);
                flags.insert("macos_optimizations".to_string(), true);
            
            _ => 
        

        // Architecture-specific flags
        match platform_info.architecture 
            Architecture::ARM64 => 
                flags.insert("arm_optimizations".to_string(), true);
            
            Architecture::X86_64 => 
                flags.insert("x64_optimizations".to_string(), true);
                flags.insert("simd_support".to_string(), true);
            
            _ => 
        

        // Memory-based flags
        if platform_info.available_memory > 4 * 1024 * 1024 * 1024 
            flags.insert("high_memory_mode".to_string(), true);
            flags.insert("large_buffer_pool".to_string(), true);
        

        // CPU-based flags
        if platform_info.cpu_cores >= 8 
            flags.insert("multi_threaded_processing".to_string(), true);
        

        // Environment-based flags
        if std::env::var("ENABLE_METRICS").is_ok() 
            flags.insert("metrics_collection".to_string(), true);
        

        if std::env::var("ENABLE_TRACING").is_ok() 
            flags.insert("distributed_tracing".to_string(), true);
        

        flags
    

    fn load_environment_variables() -> HashMap<String, String> 
        std::env::vars().collect()
    

    fn is_feature_enabled(&self, feature: &str) -> bool 
        self.feature_flags.get(feature).copied().unwrap_or(false)
    

    fn get_env_var(&self, key: &str) -> Option<&String> 
        self.environment_variables.get(key)
    
}

// Cross-platform service manager
struct UniversalServiceManager 
    config: PlatformConfig,
    health_status: std::sync::Arc<std::sync::RwLock<HealthStatus>>,
    metrics: std::sync::Arc<std::sync::RwLock<ServiceMetrics>>,


#[derive(Clone, Debug)]
struct HealthStatus 
    status: ServiceStatus,
    last_check: chrono::DateTime<chrono::Utc>,
    uptime: std::time::Duration,
    checks: HashMap<String, CheckResult>,


#[derive(Clone, Debug)]
enum ServiceStatus 
    Healthy,
    Degraded,
    Unhealthy,
    Starting,
    Stopping,


#[derive(Clone, Debug)]
struct CheckResult 
    name: String,
    status: bool,
    message: String,
    duration: std::time::Duration,


#[derive(Clone, Debug, Default)]
struct ServiceMetrics 
    requests_total: u64,
    requests_per_second: f64,
    average_response_time: std::time::Duration,
    error_rate: f64,
    memory_usage: u64,
    cpu_usage: f64,
    active_connections: u64,


impl UniversalServiceManager {
    fn new() -> Self 
        let config = PlatformConfig::detect_platform();

        Self 
            config,
            health_status: std::sync::Arc::new(std::sync::RwLock::new(HealthStatus 
                status: ServiceStatus::Starting,
                last_check: chrono::Utc::now(),
                uptime: std::time::Duration::ZERO,
                checks: HashMap::new(),
            )),
            metrics: std::sync::Arc::new(std::sync::RwLock::new(ServiceMetrics::default())),
        
    

    async fn start_service(&self) -> Result<(), String> 
        println!("Starting universal service...");
        println!("Platform: :?", self.config.platform_info.os_type);
        println!("Architecture: :?", self.config.platform_info.architecture);
        println!("Port: ", self.config.deployment_config.service_port);
        println!("Max connections: ", self.config.deployment_config.max_connections);

        // Platform-specific initialization
        self.initialize_platform_specific_features().await?;

        // Start health monitoring
        self.start_health_monitoring().await;

        // Update status
        
            let mut health = self.health_status.write().unwrap();
            health.status = ServiceStatus::Healthy;
            health.last_check = chrono::Utc::now();
        

        Ok(())
    

    async fn initialize_platform_specific_features(&self) -> Result<(), String> 
        if self.config.is_feature_enabled("epoll_support") 
            println!("Initializing epoll support for Linux");
        

        if self.config.is_feature_enabled("iocp_support") 
            println!("Initializing IOCP support for Windows");
        

        if self.config.is_feature_enabled("kqueue_support") 
            println!("Initializing kqueue support for macOS");
        

        if self.config.is_feature_enabled("high_memory_mode") 
            println!("Enabling high memory mode optimizations");
        

        if self.config.is_feature_enabled("multi_threaded_processing") 
            println!("Enabling multi-threaded processing");
        

        Ok(())
    

    async fn start_health_monitoring(&self) {
        let health_status = self.health_status.clone();
        let config = self.config.clone();

        tokio::spawn(async move 
            let mut interval = tokio::time::interval(std::time::Duration::from_secs(30));
            let start_time = std::time::Instant::now();

            loop 
                interval.tick().await;

                let mut checks = HashMap::new();

                // Memory check
                let memory_check = Self::check_memory_usage(&config).await;
                checks.insert("memory".to_string(), memory_check);

                // Disk space check
                let disk_check = Self::check_disk_space().await;
                checks.insert("disk".to_string(), disk_check);

                // Network connectivity check
                let network_check = Self::check_network_connectivity().await;
                checks.insert("network".to_string(), network_check);

                // Update health status
                check
            
        );
    }

    async fn check_memory_usage(config: &PlatformConfig) -> CheckResult 
        let start = std::time::Instant::now();

        // Simplified memory check
        let available_memory = config.platform_info.available_memory;
        let threshold = available_memory / 10; // 10% threshold

        CheckResult 
            name: "memory_usage".to_string(),
            status: true, // Simplified - always pass
            message: format!("Memory usage within limits (MB available)", available_memory / 1024 / 1024),
            duration: start.elapsed(),
        
    

    async fn check_disk_space() -> CheckResult 
        let start = std::time::Instant::now();

        CheckResult 
            name: "disk_space".to_string(),
            status: true, // Simplified - always pass
            message: "Disk space sufficient".to_string(),
            duration: start.elapsed(),
        
    

    async fn check_network_connectivity() -> CheckResult 
        let start = std::time::Instant::now();

        CheckResult 
            name: "network_connectivity".to_string(),
            status: true, // Simplified - always pass
            message: "Network connectivity OK".to_string(),
            duration: start.elapsed(),
        
    

    fn get_health_status(&self) -> HealthStatus 
        self.health_status.read().unwrap().clone()
    

    fn get_metrics(&self) -> ServiceMetrics 
        self.metrics.read().unwrap().clone()
    

    fn get_platform_info(&self) -> &PlatformConfig 
        &self.config
    
}

static SERVICE_MANAGER: once_cell::sync::Lazy<UniversalServiceManager> =
    once_cell::sync::Lazy::new(|| UniversalServiceManager::new());

// Universal endpoints
#[get]
async fn health_endpoint(ctx: Context) 
    let health_status = SERVICE_MANAGER.get_health_status();

    let status_code = match health_status.status 
        ServiceStatus::Healthy => 200,
        ServiceStatus::Degraded => 200,
        ServiceStatus::Unhealthy => 503,
        ServiceStatus::Starting => 503,
        ServiceStatus::Stopping => 503,
    ;

    ctx.set_response_status_code(status_code)
        .await
        .set_response_header(CONTENT_TYPE, APPLICATION_JSON)
        .await
        .set_response_body(serde_json::to_string(&health_status).unwrap())
        .await;


#[get]
async fn metrics_endpoint(ctx: Context) 
    let metrics = SERVICE_MANAGER.get_metrics();

    ctx.set_response_status_code(200)
        .await
        .set_response_header(CONTENT_TYPE, APPLICATION_JSON)
        .await
        .set_response_body(serde_json::to_string(&metrics).unwrap())
        .await;


#[get]
async fn platform_info_endpoint(ctx: Context) 
    let platform_config = SERVICE_MANAGER.get_platform_info();

    let response = serde_json::json!(
        "platform_info": platform_config.platform_info,
        "deployment_config": platform_config.deployment_config,
        "feature_flags": platform_config.feature_flags,
        "environment_count": platform_config.environment_variables.len()
    );

    ctx.set_response_status_code(200)
        .await
        .set_response_header(CONTENT_TYPE, APPLICATION_JSON)
        .await
        .set_response_body(serde_json::to_string(&response).unwrap())
        .await;


#[get]
async fn readiness_endpoint(ctx: Context) 
    let health_status = SERVICE_MANAGER.get_health_status();

    let is_ready = matches!(health_status.status, ServiceStatus::Healthy 

#[get]
async fn liveness_endpoint(ctx: Context) 
    // Simple liveness check - if we can respond, we're alive
    let response = serde_json::json!(
        "alive": true,
        "timestamp": chrono::Utc::now().timestamp()
    );

    ctx.set_response_status_code(200)
        .await
        .set_response_header(CONTENT_TYPE, APPLICATION_JSON)
        .await
        .set_response_body(serde_json::to_string(&response).unwrap())
        .await;


// Cross-platform deployment utilities
#[derive(Serialize)]
struct DeploymentInfo 
    platform: String,
    architecture: String,
    version: String,
    build_time: String,
    git_commit: Option<String>,
    container_info: Option<ContainerInfo>,


#[derive(Serialize)]
struct ContainerInfo 
    runtime: String,
    image_id: Option<String>,
    container_id: Option<String>,


#[get]
async fn deployment_info_endpoint(ctx: Context) 
    let platform_config = SERVICE_MANAGER.get_platform_info();

    let deployment_info = DeploymentInfo  s.to_string()),
        container_info: platform_config.deployment_config.container_runtime.as_ref().map(;

    ctx.set_response_status_code(200)
        .await
        .set_response_header(CONTENT_TYPE, APPLICATION_JSON)
        .await
        .set_response_body(serde_json::to_string(&deployment_info).unwrap())
        .await;

Enter fullscreen mode

Exit fullscreen mode

In my exploration of cross-platform deployment, I discovered that containerization provides the most reliable path to universal application deployment. Containers abstract away platform differences while providing consistent runtime environments.

The framework I’ve been studying embraces container-first deployment with intelligent platform detection and optimization. This approach ensures that applications can leverage platform-specific optimizations while maintaining portability across different environments.

One of the biggest challenges in cross-platform deployment is managing configuration across different environments. Through my experience, I learned that successful universal applications require sophisticated configuration management that adapts to platform capabilities and deployment contexts.

This article documents my exploration of cross-platform application development as a junior student. Through practical implementation and deployment experience, I learned the importance of building applications that adapt intelligently to their runtime environment while maintaining consistent functionality across platforms.



Source link