From ce97f59d2d24fc169f156d1ff936c2bd4e941a01 Mon Sep 17 00:00:00 2001 From: Gagan Trivedi Date: Sat, 31 Oct 2026 15:32:08 +0530 Subject: [PATCH] refactor: move server startup into the library --- src/lib.rs | 3 +++ src/main.rs | 58 +------------------------------------------------- src/server.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 src/server.rs diff --git a/src/lib.rs b/src/lib.rs index 2bfc72a..c13d760 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,5 +4,8 @@ pub mod environments; pub mod error; pub mod models; pub mod routes; +pub mod server; pub mod services; pub mod state; + +pub use server::run; diff --git a/src/main.rs b/src/main.rs index 405c5fd..aa74557 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,62 +1,6 @@ -use edge_proxy::config::logging::setup_logging; use edge_proxy::config::settings::get_settings; -use edge_proxy::routes::create_router; -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; -use tracing::{info, warn}; - -const DEFAULT_HOST: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); #[tokio::main] async fn main() -> anyhow::Result<()> { - let settings = get_settings()?; - - setup_logging(&settings.logging); - - info!("Starting Edge Proxy server..."); - info!("API URL: {}", settings.api_url); - info!( - "Polling frequency: {}s", - settings.api_poll_frequency_seconds - ); - - // serde defaults these fields, so a typo'd field name parses as an - // empty set and the proxy would report healthy while rejecting every - // request — make that state loud. - if settings.environment_key_pairs.is_empty() && settings.proxy_key.is_none() { - warn!( - "No environments configured: environment_key_pairs and proxy_key \ - are both empty or missing, so every request will be rejected \ - with 401" - ); - } - - let (app, environment_service) = create_router(settings.clone()); - - // Refreshes must never overlap: a delayed older poll finishing after a - // newer one could restore removed environments or rotated keys. The - // poll loop is serial, so it just has to start after the initial - // refresh completes. - info!("Loading initial environment data..."); - environment_service.refresh_environment_caches().await; - - let polling_service = environment_service.clone(); - tokio::spawn(async move { - polling_service.poll_environments().await; - }); - - let addr = SocketAddr::from(( - settings - .server - .host - .parse::() - .unwrap_or(DEFAULT_HOST), - settings.server.port, - )); - - info!("Listening on {}", addr); - - let listener = tokio::net::TcpListener::bind(addr).await?; - axum::serve(listener, app).await?; - - Ok(()) + edge_proxy::run(get_settings()?).await } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..0ccba09 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,59 @@ +use crate::config::AppSettings; +use crate::config::logging::setup_logging; +use crate::routes::create_router; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use tracing::{info, warn}; + +const DEFAULT_HOST: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + +pub async fn run(settings: AppSettings) -> anyhow::Result<()> { + setup_logging(&settings.logging); + + info!("Starting Edge Proxy server..."); + info!("API URL: {}", settings.api_url); + info!( + "Polling frequency: {}s", + settings.api_poll_frequency_seconds + ); + + // serde defaults these fields, so a typo'd field name parses as an + // empty set and the proxy would report healthy while rejecting every + // request — make that state loud. + if settings.environment_key_pairs.is_empty() && settings.proxy_key.is_none() { + warn!( + "No environments configured: environment_key_pairs and proxy_key \ + are both empty or missing, so every request will be rejected \ + with 401" + ); + } + + let (app, environment_service) = create_router(settings.clone()); + + // Refreshes must never overlap: a delayed older poll finishing after a + // newer one could restore removed environments or rotated keys. The + // poll loop is serial, so it just has to start after the initial + // refresh completes. + info!("Loading initial environment data..."); + environment_service.refresh_environment_caches().await; + + let polling_service = environment_service.clone(); + tokio::spawn(async move { + polling_service.poll_environments().await; + }); + + let addr = SocketAddr::from(( + settings + .server + .host + .parse::() + .unwrap_or(DEFAULT_HOST), + settings.server.port, + )); + + info!("Listening on {}", addr); + + let listener = tokio::net::TcpListener::bind(addr).await?; + axum::serve(listener, app).await?; + + Ok(()) +}