use dtmrs::server::api::Api;
use dtmrs::server::driver::Driver;
use dtmrs::server::http::{router, App};
use dtmrs::Store;
use std::time::Duration;
use tracing::info;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()),
)
.init();
let db = std::env::var("DTMRS_DB").unwrap_or_else(|_| "sqlite:dtmrs.db".into());
let addr = std::env::var("DTMRS_ADDR").unwrap_or_else(|_| "0.0.0.0:36789".into());
let grpc_addr = std::env::var("DTMRS_GRPC_ADDR").unwrap_or_else(|_| "0.0.0.0:36790".into());
let owner =
std::env::var("DTMRS_OWNER").unwrap_or_else(|_| format!("tc-{}", std::process::id()));
let tick_ms: u64 = std::env::var("DTMRS_TICK_MS")
.ok()
.and_then(|v| v.parse().ok())
.filter(|v| *v > 0)
.unwrap_or(1000);
let store = Store::open(&db).await?;
let driver = Driver::from_env(store.clone(), owner.clone());
info!(db = %db, http = %addr, grpc = %grpc_addr, owner = %owner,
branch_timeout = driver.http_timeout_secs(), lease = driver.lease,
retry_initial = driver.retry.initial, retry_max = driver.retry.max, tick_ms,
"dtmrs 启动");
tokio::spawn(driver.clone().run_forever(Duration::from_millis(tick_ms)));
let inline = !matches!(
std::env::var("DTMRS_INLINE_SUBMIT").as_deref(),
Ok("0") | Ok("false")
);
let api = if inline {
Api::new(store).with_inline_driver(driver.clone())
} else {
Api::new(store)
};
info!(inline_submit = inline, "提交后是否直接开推");
let grpc = serve_grpc(api.clone(), grpc_addr);
let http = serve_http(api, addr);
tokio::select! {
r = grpc => r?,
r = http => r?,
}
Ok(())
}
async fn serve_http(api: Api, addr: String) -> anyhow::Result<()> {
let listener = tokio::net::TcpListener::bind(&addr).await?;
axum::serve(listener, router(App::new(api))).await?;
Ok(())
}
#[cfg(feature = "grpc")]
async fn serve_grpc(api: Api, addr: String) -> anyhow::Result<()> {
use dtmrs::server::grpc::server::TcService;
let sock = addr.parse()?;
tonic::transport::Server::builder()
.add_service(TcService::new(api).into_server())
.serve(sock)
.await?;
Ok(())
}
#[cfg(not(feature = "grpc"))]
async fn serve_grpc(_api: Api, _addr: String) -> anyhow::Result<()> {
std::future::pending::<()>().await;
Ok(())
}