very fast at protocol indexer with flexible filtering, xrpc queries, cursor-backed event stream, and more, built on fjall
rust
fjall
at-protocol
atproto
indexer
1use futures::FutureExt;
2use hydrant::config::Config;
3use hydrant::control::Hydrant;
4use mimalloc::MiMalloc;
5
6struct AppConfig {
7 api_port: u16,
8 enable_debug: bool,
9 debug_port: u16,
10}
11
12impl AppConfig {
13 fn from_env() -> Self {
14 use hydrant::__cfg as cfg;
15 let api_port = cfg!("API_PORT", 3000u16);
16 let enable_debug = cfg!("ENABLE_DEBUG", false);
17 let debug_port: u16 = api_port + 1;
18 let debug_port = cfg!("DEBUG_PORT", debug_port);
19 Self {
20 api_port,
21 enable_debug,
22 debug_port,
23 }
24 }
25}
26
27#[global_allocator]
28static GLOBAL: MiMalloc = MiMalloc;
29
30#[tokio::main]
31async fn main() -> miette::Result<()> {
32 rustls::crypto::aws_lc_rs::default_provider()
33 .install_default()
34 .ok();
35
36 let cfg = Config::from_env()?;
37 let app = AppConfig::from_env();
38
39 let env_filter = tracing_subscriber::EnvFilter::builder()
40 .with_default_directive(tracing::Level::INFO.into())
41 .from_env_lossy();
42 tracing_subscriber::fmt().with_env_filter(env_filter).init();
43
44 let hydrant = Hydrant::new(cfg).await?;
45
46 let debug_fut = app
47 .enable_debug
48 .then(|| hydrant.serve_debug(app.debug_port).boxed())
49 .unwrap_or_else(|| std::future::pending().boxed());
50
51 tokio::select! {
52 r = hydrant.run()? => r,
53 r = hydrant.serve(app.api_port) => r,
54 r = debug_fut => r,
55 }
56}