forked from SO4-Markets/so4-oracle
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.rs
More file actions
109 lines (91 loc) · 3.14 KB
/
Copy pathmain.rs
File metadata and controls
109 lines (91 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use std::sync::Arc;
use oracle::{api, AppState, Config};
use tokio::net::TcpListener;
use tokio_util::sync::CancellationToken;
use tracing_subscriber::EnvFilter;
#[tokio::main]
async fn main() {
init_tracing();
dotenvy::dotenv().ok();
let config = match Config::from_env() {
Ok(config) => Arc::new(config),
Err(errors) => {
for error in &errors.0 {
tracing::error!(%error, "configuration failed");
}
std::process::exit(1);
}
};
let bind_addr = config.bind_addr;
let state = Arc::new(AppState::new(Arc::clone(&config)));
let app = api::build_router(Arc::clone(&state));
#[allow(unused_mut)]
let listener = match TcpListener::bind(bind_addr).await {
Ok(listener) => listener,
Err(error) => {
tracing::error!(%error, %bind_addr, "failed to bind listener");
std::process::exit(1);
}
};
let price_loop = tokio::spawn(oracle::price_loop::run_price_loop(Arc::clone(&state)));
let keeper_loop = tokio::spawn(oracle::keeper_loop::run_keeper_loop(Arc::clone(&state)));
tracing::info!(
%bind_addr,
network = config.network.as_str(),
"oracle server listening"
);
let shutdown_token = state.shutdown_token.clone();
let server_future =
axum::serve(listener, app).with_graceful_shutdown(shutdown_signal(shutdown_token.clone()));
let server_result =
tokio::time::timeout(std::time::Duration::from_secs(30), server_future).await;
match server_result {
Ok(Ok(())) => {}
Ok(Err(error)) => {
tracing::error!(%error, "server error");
std::process::exit(1);
}
Err(_) => {
tracing::warn!("server shutdown timed out after 30s, canceling background tasks");
}
}
tracing::info!("shutdown initiated, draining...");
state.shutdown_token.cancel();
let _ = tokio::join!(price_loop, keeper_loop);
}
fn init_tracing() {
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::fmt()
.json()
.with_env_filter(filter)
.with_current_span(true)
.with_span_list(true)
.init();
}
async fn shutdown_signal(token: CancellationToken) {
let ctrl_c = async {
if let Err(error) = tokio::signal::ctrl_c().await {
tracing::error!(%error, "failed to install SIGINT handler");
std::future::pending::<()>().await;
}
};
#[cfg(unix)]
let terminate = async {
match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) {
Ok(mut signal) => {
signal.recv().await;
}
Err(error) => {
tracing::error!(%error, "failed to install SIGTERM handler");
std::future::pending::<()>().await;
}
}
};
#[cfg(not(unix))]
let terminate = std::future::pending::<()>();
tokio::select! {
_ = ctrl_c => tracing::info!("received SIGINT"),
_ = terminate => tracing::info!("received SIGTERM"),
}
token.cancel();
}