1use clap::Parser;
2use std::{error::Error, net::SocketAddr};
3use tokio::{
4 task,
5 time::{sleep, Duration},
6};
7use tracing::{error, info};
8use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
9
10type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
11
12mod access;
13mod api;
14mod app;
15mod config;
16mod error;
17
18#[derive(Parser, Debug)]
19#[command(author, version, about, long_about = None)]
20pub struct Args {
21 #[arg(short, long)]
23 pub data_dir: Option<String>,
24
25 #[arg(short, long)]
27 pub enable_security_api_keys: Option<bool>,
28
29 #[arg(short, long)]
31 pub port: Option<u16>,
32
33 #[arg(long)]
35 pub save_triggered_by_threshold: Option<u16>,
36
37 #[arg(long)]
39 pub save_triggered_after_ms: Option<i64>,
40
41 #[arg(long)]
43 pub sleep_time_between_gc_ms: Option<u64>,
44
45 #[arg(long)]
47 pub sleep_time_between_saves_ms: Option<u64>,
48}
49
50pub async fn run() -> Result<()> {
51 tracing_subscriber::registry()
52 .with(
53 tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
54 "alex_db_server=error,runtime=error,tokio=error,tower_http=error".into()
55 }),
56 )
57 .with(tracing_subscriber::fmt::layer())
58 .init();
59
60 let args = Args::parse();
61 let config = config::load(args)?;
62
63 let app = app::get_app(config.clone()).await?;
64
65 let db_for_deleting = app.db.clone();
66 task::spawn(async move {
67 loop {
68 let res = db_for_deleting.gc();
69
70 if let Err(e) = res {
71 error!("Error: {:?}", e);
72 }
73
74 sleep(Duration::from_millis(
75 config.db_config.sleep_time_between_gc_ms,
76 ))
77 .await;
78 }
79 });
80
81 let db_for_saving = app.db;
82 task::spawn(async move {
83 loop {
84 let res = db_for_saving.save();
85
86 if let Err(e) = res {
87 error!("Error: {:?}", e);
88 }
89
90 sleep(Duration::from_millis(
91 config.db_config.sleep_time_between_saves_ms,
92 ))
93 .await;
94 }
95 });
96
97 let addr = SocketAddr::from(([0, 0, 0, 0], config.port));
98 info!("listening on {}", addr);
99 axum::Server::bind(&addr)
100 .serve(app.router.into_make_service())
101 .await
102 .unwrap();
103
104 Ok(())
105}