mod config; mod error; mod image; mod model; mod routes; mod telemetry; use anyhow::Result; use config::Config; use model::ModelService; use routes::{router, AppState}; use std::sync::Arc; use tokio::net::TcpListener; use tracing_subscriber::EnvFilter; #[tokio::main] async fn main() -> Result<()> { // Initialize tracing subscriber with EnvFilter tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .init(); // Load configuration from environment let config = Config::from_env()?; // Create ModelService with calibration and wrap in Arc let model = Arc::new(ModelService::with_calibration( &config.model_path, config.input_size, config.temperature, config.conf_threshold_high, config.conf_threshold_low, )); tracing::info!( model_loaded = model.is_loaded(), model_path = ?config.model_path, temperature = config.temperature, conf_high = config.conf_threshold_high, conf_low = config.conf_threshold_low, "Model service initialized" ); // Set model load status metric telemetry::model_load_status().set(if model.is_loaded() { 1.0 } else { 0.0 }); // Create AppState let state = AppState { model }; // Bind TcpListener to host:port let addr = format!("{}:{}", config.host, config.port); let listener = TcpListener::bind(&addr).await?; tracing::info!(address = %addr, "Server listening"); // Serve with Axum axum::serve(listener, router(state)).await?; Ok(()) }