use anyhow::Result; use clap::Parser; use std::{borrow::Cow, net::SocketAddr, str::FromStr, sync::Arc}; use tokio::sync::mpsc; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; use cerulea_relay::{ http::{self}, relay::index::index_servers, sequencer::start_sequencer, AppState, }; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { /// Bind address for the service #[arg(short, long, default_value = "127.0.0.1:3000")] bind_addr: SocketAddr, /// Database RAM cache capacity in megabytes #[arg(long, default_value_t = 1024)] cache_capacity: u64, /// did:plc directory HTTPS host. defaults to plc.directory if unset #[arg(long)] plc_resolver: Option, #[arg(long)] drop_user_cache: bool, } #[tokio::main] async fn main() -> Result<()> { let args = Args::parse(); tracing_subscriber::registry() .with(fmt::layer()) .with(EnvFilter::from_str("cerulea_relay=debug").unwrap()) .init(); let db = sled::Config::default() .path("data") .cache_capacity(args.cache_capacity * 1024 * 1024) .use_compression(true) .open() .expect("Failed to open database"); if args.drop_user_cache { let _ = db.drop_tree("users"); } let (event_tx, event_rx) = mpsc::channel(128); let mut server = AppState::new(db, event_tx); if let Some(plc_directory) = args.plc_resolver { server.plc_resolver = Cow::Owned(plc_directory); } let server = Arc::new(server); let initial_hosts: Vec = { let hosts = server.known_good_hosts.lock().await; hosts.iter().cloned().collect() }; tracing::debug!(hosts = ?initial_hosts, "got initial hosts"); index_servers(Arc::clone(&server), &initial_hosts); start_sequencer(Arc::clone(&server), event_rx); http::listen(server, args.bind_addr).await?; Ok(()) }