mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 04:51:13 +03:00
Compare commits
2 commits
45aa79da6d
...
13e2a54eb2
| Author | SHA1 | Date | |
|---|---|---|---|
| 13e2a54eb2 | |||
| b02cca8608 |
6 changed files with 39 additions and 32 deletions
|
|
@ -15,7 +15,6 @@ pub async fn initial(
|
||||||
ws.on_upgrade(|socket| handle_socket(socket, state))
|
ws.on_upgrade(|socket| handle_socket(socket, state))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
|
||||||
async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
// Trying authenticate & get user data or dropping connection
|
// Trying authenticate & get user data or dropping connection
|
||||||
match authenticate(&mut ws, &state).await {
|
match authenticate(&mut ws, &state).await {
|
||||||
|
|
@ -65,7 +64,7 @@ async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||||
if let Err(kind) = ws.send(Message::Close(None)).await { tracing::trace!("[WebSocket] Closing fault: {}", kind) }
|
if let Err(kind) = ws.send(Message::Close(None)).await { tracing::trace!("[WebSocket] Closing fault: {}", kind) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all, parent = None, fields(nickname = %session.user.nickname))]
|
#[instrument(skip_all, fields(nickname = %session.user.nickname))]
|
||||||
async fn main_worker(session: &mut WSSession, ws: &mut WebSocket, state: &AppState) -> anyhow::Result<()> {
|
async fn main_worker(session: &mut WSSession, ws: &mut WebSocket, state: &AppState) -> anyhow::Result<()> {
|
||||||
tracing::debug!("WebSocket control for {} is transferred to the main worker", session.user.nickname);
|
tracing::debug!("WebSocket control for {} is transferred to the main worker", session.user.nickname);
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ impl From<C2SMessage> for Vec<u8> {
|
||||||
impl C2SMessage {
|
impl C2SMessage {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
C2SMessage::Token(_) => "c2s>token",
|
C2SMessage::Token(_) => "C2S;TOKEN",
|
||||||
C2SMessage::Ping(_, _, _) => "c2s>ping",
|
C2SMessage::Ping(_, _, _) => "C2S;PING",
|
||||||
C2SMessage::Sub(_) => "c2s>sub",
|
C2SMessage::Sub(_) => "C2S;SUB",
|
||||||
C2SMessage::Unsub(_) => "c2s>unsub",
|
C2SMessage::Unsub(_) => "C2S;UNSUB",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,12 @@ impl From<S2CMessage> for Vec<u8> {
|
||||||
impl S2CMessage {
|
impl S2CMessage {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
S2CMessage::Auth => "s2c>auth",
|
S2CMessage::Auth => "S2C;AUTH",
|
||||||
S2CMessage::Ping(_, _, _, _) => "s2c>ping",
|
S2CMessage::Ping(_, _, _, _) => "S2C;PING",
|
||||||
S2CMessage::Event(_) => "s2c>event",
|
S2CMessage::Event(_) => "S2C;EVENT",
|
||||||
S2CMessage::Toast(_, _, _) => "s2c>toast",
|
S2CMessage::Toast(_, _, _) => "S2C;TOAST",
|
||||||
S2CMessage::Chat(_) => "s2c>chat",
|
S2CMessage::Chat(_) => "S2C;CHAT",
|
||||||
S2CMessage::Notice(_) => "s2c>notice",
|
S2CMessage::Notice(_) => "S2C;NOTICE",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
|
||||||
|
|
||||||
// Figura update checker
|
// Figura update checker
|
||||||
pub const FIGURA_RELEASES_URL: &str = "https://api.github.com/repos/figuramc/figura/releases";
|
pub const FIGURA_RELEASES_URL: &str = "https://api.github.com/repos/figuramc/figura/releases";
|
||||||
pub const FIGURA_DEFAULT_VERSION: &str = "0.1.4";
|
pub const FIGURA_DEFAULT_VERSION: &str = "0.1.5";
|
||||||
|
|
||||||
// Figura Assets
|
// Figura Assets
|
||||||
pub const FIGURA_ASSETS_ZIP_URL: &str = "https://github.com/FiguraMC/Assets/archive/refs/heads/main.zip";
|
pub const FIGURA_ASSETS_ZIP_URL: &str = "https://github.com/FiguraMC/Assets/archive/refs/heads/main.zip";
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -105,6 +105,13 @@ async fn main() -> Result<()> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creating avatars folder
|
||||||
|
let path = PathBuf::from(&*AVATARS_VAR);
|
||||||
|
if !path.exists() {
|
||||||
|
fs::create_dir_all(path).await.expect("Can't create avatars folder!");
|
||||||
|
tracing::info!("Created avatars directory");
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Starting an app() that starts to serve. If app() returns true, the sculptor will be restarted. TODO: for future
|
// 4. Starting an app() that starts to serve. If app() returns true, the sculptor will be restarted. TODO: for future
|
||||||
loop {
|
loop {
|
||||||
if !app().await? {
|
if !app().await? {
|
||||||
|
|
@ -116,15 +123,6 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn app() -> Result<bool> {
|
async fn app() -> Result<bool> {
|
||||||
// Preparing for launch
|
|
||||||
{
|
|
||||||
let path = PathBuf::from(&*AVATARS_VAR);
|
|
||||||
if !path.exists() {
|
|
||||||
fs::create_dir_all(path).await.expect("Can't create avatars folder!");
|
|
||||||
tracing::info!("Created avatars directory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
let config = Config::parse(CONFIG_VAR.clone().into());
|
let config = Config::parse(CONFIG_VAR.clone().into());
|
||||||
let listen = config.listen.clone();
|
let listen = config.listen.clone();
|
||||||
|
|
@ -198,6 +196,8 @@ async fn app() -> Result<bool> {
|
||||||
.nest("/api", api)
|
.nest("/api", api)
|
||||||
.route("/api/", get(check_auth))
|
.route("/api/", get(check_auth))
|
||||||
.route("/ws", get(ws))
|
.route("/ws", get(ws))
|
||||||
|
.merge(metrics::metrics_router(config.metrics_enabled))
|
||||||
|
.with_state(state)
|
||||||
.layer(TraceLayer::new_for_http()
|
.layer(TraceLayer::new_for_http()
|
||||||
// .on_request(|request: &axum::http::Request<_>, _span: &tracing::Span| {
|
// .on_request(|request: &axum::http::Request<_>, _span: &tracing::Span| {
|
||||||
// // only for developing purposes
|
// // only for developing purposes
|
||||||
|
|
@ -209,8 +209,6 @@ async fn app() -> Result<bool> {
|
||||||
.on_request(())
|
.on_request(())
|
||||||
)
|
)
|
||||||
.layer(axum::middleware::from_fn(track_metrics))
|
.layer(axum::middleware::from_fn(track_metrics))
|
||||||
.merge(metrics::metrics_router(config.metrics_enabled))
|
|
||||||
.with_state(state)
|
|
||||||
.route("/health", get(|| async { "ok" }));
|
.route("/health", get(|| async { "ok" }));
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind(listen).await?;
|
let listener = tokio::net::TcpListener::bind(listen).await?;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ async fn metrics(State(state): State<AppState>) -> String {
|
||||||
let mut metric = prometheus::proto::Metric::default();
|
let mut metric = prometheus::proto::Metric::default();
|
||||||
metric.set_gauge(prometheus::proto::Gauge::default());
|
metric.set_gauge(prometheus::proto::Gauge::default());
|
||||||
metric.mut_gauge().set_value(state.session.len() as f64);
|
metric.mut_gauge().set_value(state.session.len() as f64);
|
||||||
create_mf("players_count".to_string(), "Number of players".to_string(), MetricType::GAUGE, metric)
|
create_mf("sculptor_players_count".to_string(), "Number of players".to_string(), MetricType::GAUGE, metric)
|
||||||
};
|
};
|
||||||
|
|
||||||
metric_families.push(players);
|
metric_families.push(players);
|
||||||
|
|
@ -43,8 +43,10 @@ fn create_mf(name: String, help: String, field_type: MetricType, metric: Metric)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn track_metrics(req: Request<Body>, next: Next) -> Result<Response<Body>, StatusCode> {
|
pub async fn track_metrics(req: Request<Body>, next: Next) -> Result<Response<Body>, StatusCode> {
|
||||||
|
let method = req.method().to_string();
|
||||||
|
let route = http_route(&req).to_string();
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let uri = req.uri().path().to_string();
|
|
||||||
|
|
||||||
// Call the next middleware or handler
|
// Call the next middleware or handler
|
||||||
let response = next.run(req).await;
|
let response = next.run(req).await;
|
||||||
|
|
@ -52,20 +54,28 @@ pub async fn track_metrics(req: Request<Body>, next: Next) -> Result<Response<Bo
|
||||||
let latency = start.elapsed().as_secs_f64();
|
let latency = start.elapsed().as_secs_f64();
|
||||||
|
|
||||||
REQUESTS
|
REQUESTS
|
||||||
.with_label_values(&[&uri, response.status().as_str()])
|
.with_label_values(&[&method, &route, response.status().as_str()])
|
||||||
.observe(latency);
|
.observe(latency);
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static PINGS_ERROR: LazyLock<prometheus::IntCounter> = LazyLock::new(|| {
|
// https://github.com/davidB/tracing-opentelemetry-instrumentation-sdk/blob/main/axum-tracing-opentelemetry/src/middleware/trace_extractor.rs#L177
|
||||||
register_int_counter!("pings_error", "Number of ping decoding errors").unwrap()
|
#[inline]
|
||||||
});
|
fn http_route<B>(req: &Request<B>) -> &str {
|
||||||
|
req.extensions()
|
||||||
|
.get::<axum::extract::MatchedPath>()
|
||||||
|
.map_or_else(|| "", |mp| mp.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
pub static REQUESTS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
pub static REQUESTS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
||||||
register_histogram_vec!("requests_count", "Number of requests", &["uri", "code"], vec![0.025, 0.250, 0.500]).unwrap()
|
register_histogram_vec!("sculptor_requests_count", "Number of requests", &["method", "uri", "code"], vec![0.025, 0.250, 0.500]).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
pub static PINGS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
pub static PINGS: LazyLock<prometheus::HistogramVec> = LazyLock::new(|| {
|
||||||
register_histogram_vec!("pings_count", "Number of pings", &["type"], vec![0.000003, 0.00002, 0.0002]).unwrap()
|
register_histogram_vec!("sculptor_pings_count", "Number of pings", &["type"], vec![0.000001, 0.00001, 0.0001]).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
pub static PINGS_ERROR: LazyLock<prometheus::IntCounter> = LazyLock::new(|| {
|
||||||
|
register_int_counter!("sculptor_pings_error", "Number of ping decoding errors").unwrap()
|
||||||
});
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue