From 1a053b6d2867d84de8211fea2f75e6f544e5a12c Mon Sep 17 00:00:00 2001 From: cmyui Date: Wed, 25 Oct 2023 02:36:16 -0400 Subject: [PATCH 01/17] temp disable prod deploys --- .github/workflows/production-deploy.yml | 49 +++++++++++++------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/production-deploy.yml b/.github/workflows/production-deploy.yml index 88046be..16f8a10 100644 --- a/.github/workflows/production-deploy.yml +++ b/.github/workflows/production-deploy.yml @@ -1,25 +1,26 @@ -name: production-deploy -on: - push: - branches: - - main +# TODO: fix production deploys +# name: production-deploy +# on: +# push: +# branches: +# - main -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - name: Run deploy on production - uses: appleboy/ssh-action@v1.0.0 - with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - port: ${{ secrets.SSH_PORT }} - script_stop: true - script: | - cd /home/akatsuki/performance-service - git pull origin main - docker build -t performance-service:latest . - cd /home/akatsuki/workbench - docker-compose restart performance-service-api performance-service-processor +# jobs: +# build: +# name: Build +# runs-on: ubuntu-latest +# steps: +# - name: Run deploy on production +# uses: appleboy/ssh-action@v1.0.0 +# with: +# host: ${{ secrets.SSH_HOST }} +# username: ${{ secrets.SSH_USERNAME }} +# key: ${{ secrets.SSH_KEY }} +# port: ${{ secrets.SSH_PORT }} +# script_stop: true +# script: | +# cd /home/akatsuki/performance-service +# git pull origin main +# docker build -t performance-service:latest . +# cd /home/akatsuki/workbench +# docker-compose restart performance-service-api performance-service-processor From 43f5d929b8c93063b003bd1343674159af880cfc Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Sun, 5 Nov 2023 14:14:29 -0500 Subject: [PATCH 02/17] add API_HOST env var (#4) --- .env.example | 3 ++- src/api/mod.rs | 3 ++- src/config.rs | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 9aae7f9..bbe8d53 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ APP_ENV=dev +API_HOST=127.0.0.1 API_PORT=8665 DATABASE_HOST=localhost DATABASE_PORT=3306 @@ -18,4 +19,4 @@ REDIS_PASSWORD= REDIS_DATABASE=0 BEATMAPS_PATH= SERVICE_READINESS_TIMEOUT=60 -RUST_LOG=performance_service=info \ No newline at end of file +RUST_LOG=performance_service=info diff --git a/src/api/mod.rs b/src/api/mod.rs index 515b589..4f3af62 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -21,6 +21,7 @@ fn api_router() -> Router { pub async fn serve(ctx: Context) -> anyhow::Result<()> { let server_port = ctx.config.api_port.unwrap(); + let server_host = ctx.config.api_host.clone().unwrap(); let app = api_router().layer( ServiceBuilder::new() @@ -29,7 +30,7 @@ pub async fn serve(ctx: Context) -> anyhow::Result<()> { ); log::info!("serving on {}", server_port); - axum::Server::bind(&format!("127.0.0.1:{}", server_port).parse()?) + axum::Server::bind(&format!("{}:{}", server_host, server_port).parse()?) .serve(app.into_make_service()) .await?; diff --git a/src/config.rs b/src/config.rs index 34485db..46a90b6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,6 +3,9 @@ pub struct Config { #[clap(long, env)] pub app_component: String, + #[clap(long, env)] + pub api_host: Option, + #[clap(long, env)] pub api_port: Option, From d410144277fa425f46d93155603c6ffd6ef84df9 Mon Sep 17 00:00:00 2001 From: cmyui Date: Sun, 5 Nov 2023 14:27:13 -0500 Subject: [PATCH 03/17] add log case for calculated pp; add warning log cases for failures --- src/api/routes/calculate.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/api/routes/calculate.rs b/src/api/routes/calculate.rs index 5d68897..f7749c3 100644 --- a/src/api/routes/calculate.rs +++ b/src/api/routes/calculate.rs @@ -60,11 +60,13 @@ async fn calculate_relax_pp( let mut pp = round(result.pp as f32, 2); if pp.is_infinite() || pp.is_nan() { + log::warn!("Calculated pp is infinite or NaN, setting to 0"); pp = 0.0; } let mut stars = round(result.difficulty.stars as f32, 2); if stars.is_infinite() || stars.is_nan() { + log::warn!("Calculated star rating is infinite or NaN, setting to 0"); stars = 0.0; } @@ -108,11 +110,13 @@ async fn calculate_rosu_pp(beatmap_path: PathBuf, request: &CalculateRequest) -> let mut pp = round(result.pp() as f32, 2); if pp.is_infinite() || pp.is_nan() { + log::warn!("Calculated pp is infinite or NaN, setting to 0"); pp = 0.0; } let mut stars = round(result.stars() as f32, 2); if stars.is_infinite() || stars.is_nan() { + log::warn!("Calculated star rating is infinite or NaN, setting to 0"); stars = 0.0; } @@ -184,6 +188,10 @@ async fn calculate_play( max_combo: 0, }); + log::warn!( + "Failed to download beatmap {} from 3rd party", + request.beatmap_id + ); continue; } } @@ -195,6 +203,11 @@ async fn calculate_play( calculate_rosu_pp(beatmap_path, &request).await }; + log::info!( + "Calculated performance: {}pp for beatmap {}", + result.pp, + request.beatmap_id + ); results.push(result); } From d8252856b2b079b90e6dbc07b6b223ac128196e4 Mon Sep 17 00:00:00 2001 From: James Date: Sun, 12 Nov 2023 10:13:08 +0000 Subject: [PATCH 04/17] massive code cleanups (#6) --- src/api/error.rs | 25 +++++++++++++ src/api/mod.rs | 1 + src/api/routes/reworks/leaderboard.rs | 9 ++--- src/api/routes/reworks/queue.rs | 10 ++--- src/api/routes/reworks/reworks.rs | 17 ++++----- src/api/routes/reworks/scores.rs | 27 +++++++------- src/api/routes/reworks/search.rs | 16 ++++---- src/api/routes/reworks/sessions.rs | 18 +++++---- src/api/routes/reworks/user.rs | 53 ++++++++++++--------------- src/deploy/mod.rs | 22 +++++------ src/main.rs | 2 +- src/mass_recalc/mod.rs | 39 +++++++++----------- src/models/pool.rs | 7 +--- src/models/score.rs | 5 +++ src/processor/mod.rs | 27 +++++++++----- src/repositories/leaderboards.rs | 6 +-- src/repositories/sessions.rs | 18 +++------ src/usecases/sessions.rs | 51 ++++++++++++-------------- 18 files changed, 177 insertions(+), 176 deletions(-) create mode 100644 src/api/error.rs diff --git a/src/api/error.rs b/src/api/error.rs new file mode 100644 index 0000000..55c54bd --- /dev/null +++ b/src/api/error.rs @@ -0,0 +1,25 @@ +use axum::{body::Body, http::Response, response::IntoResponse}; + +pub struct AppError(anyhow::Error); +pub type AppResult = Result; + +impl IntoResponse for AppError { + type Body = Body; + type BodyError = ::Error; + + fn into_response(self) -> Response { + Response::builder() + .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("internal server error")) + .unwrap() + } +} + +impl From for AppError +where + E: Into, +{ + fn from(err: E) -> Self { + Self(err.into()) + } +} diff --git a/src/api/mod.rs b/src/api/mod.rs index 4f3af62..60bd933 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -6,6 +6,7 @@ use tower_http::trace::TraceLayer; use crate::context::Context; +mod error; mod routes; fn api_router() -> Router { diff --git a/src/api/routes/reworks/leaderboard.rs b/src/api/routes/reworks/leaderboard.rs index 5819846..f67c61a 100644 --- a/src/api/routes/reworks/leaderboard.rs +++ b/src/api/routes/reworks/leaderboard.rs @@ -6,7 +6,7 @@ use axum::{ Json, Router, }; -use crate::{context::Context, models::leaderboard::Leaderboard, usecases}; +use crate::{api::error::AppResult, context::Context, models::leaderboard::Leaderboard, usecases}; pub fn router() -> Router { Router::new().route( @@ -25,15 +25,14 @@ async fn get_rework_leaderboards( Extension(ctx): Extension>, Path(rework_id): Path, Query(query): Query, -) -> Json> { +) -> AppResult>> { let leaderboard = usecases::leaderboards::fetch_one( rework_id, (query.page.max(1) - 1) * query.amount, query.amount, ctx.clone(), ) - .await - .unwrap(); + .await?; - Json(leaderboard) + Ok(Json(leaderboard)) } diff --git a/src/api/routes/reworks/queue.rs b/src/api/routes/reworks/queue.rs index de0a284..db90f53 100644 --- a/src/api/routes/reworks/queue.rs +++ b/src/api/routes/reworks/queue.rs @@ -6,7 +6,7 @@ use axum::{ Json, Router, }; -use crate::{context::Context, models::queue::QueueResponse, usecases}; +use crate::{api::error::AppResult, context::Context, models::queue::QueueResponse, usecases}; pub fn router() -> Router { Router::new().route("/api/v1/reworks/:rework_id/queue", post(send_to_queue)) @@ -21,10 +21,8 @@ async fn send_to_queue( Extension(ctx): Extension>, Path(rework_id): Path, Query(query): Query, -) -> Json { - let response = usecases::sessions::enqueue(query.session, rework_id, ctx.clone()) - .await - .unwrap(); +) -> AppResult> { + let response = usecases::sessions::enqueue(query.session, rework_id, ctx.clone()).await?; - Json(response) + Ok(Json(response)) } diff --git a/src/api/routes/reworks/reworks.rs b/src/api/routes/reworks/reworks.rs index fe3050d..3fa2580 100644 --- a/src/api/routes/reworks/reworks.rs +++ b/src/api/routes/reworks/reworks.rs @@ -6,7 +6,7 @@ use axum::{ Json, Router, }; -use crate::{context::Context, models::rework::Rework, usecases}; +use crate::{api::error::AppResult, context::Context, models::rework::Rework, usecases}; pub fn router() -> Router { Router::new() @@ -14,18 +14,15 @@ pub fn router() -> Router { .route("/api/v1/reworks/:rework_id", get(get_rework)) } -async fn get_reworks(Extension(ctx): Extension>) -> Json> { - let reworks = usecases::reworks::fetch_all(ctx.clone()).await.unwrap(); - Json(reworks) +async fn get_reworks(Extension(ctx): Extension>) -> AppResult>> { + let reworks = usecases::reworks::fetch_all(ctx.clone()).await?; + Ok(Json(reworks)) } async fn get_rework( Extension(ctx): Extension>, Path(rework_id): Path, -) -> Json> { - let rework = usecases::reworks::fetch_one(rework_id, ctx.clone()) - .await - .unwrap(); - - Json(rework) +) -> AppResult>> { + let rework = usecases::reworks::fetch_one(rework_id, ctx.clone()).await?; + Ok(Json(rework)) } diff --git a/src/api/routes/reworks/scores.rs b/src/api/routes/reworks/scores.rs index 4b3e5f5..110abe2 100644 --- a/src/api/routes/reworks/scores.rs +++ b/src/api/routes/reworks/scores.rs @@ -7,6 +7,7 @@ use axum::{ }; use crate::{ + api::error::AppResult, context::Context, models::{ beatmap::Beatmap, @@ -24,10 +25,11 @@ pub fn router() -> Router { async fn get_rework_scores( ctx: Extension>, Path((rework_id, user_id)): Path<(i32, i32)>, -) -> Json>> { +) -> AppResult>>> { let base_scores: Vec = sqlx::query_as( - "SELECT user_id, rework_scores.beatmap_id, rework_scores.beatmapset_id, rework_id, score_id, rework_scores.max_combo, mods, accuracy, score, num_300s, num_100s, num_50s, num_gekis, + "SELECT user_id, rework_scores.beatmap_id, rework_scores.beatmapset_id, beatmaps.song_name, rework_id, + score_id, rework_scores.max_combo, mods, accuracy, score, num_300s, num_100s, num_50s, num_gekis, num_katus, num_misses, old_pp, new_pp, DENSE_RANK() OVER (ORDER BY old_pp DESC) old_rank, DENSE_RANK() OVER (ORDER BY new_pp DESC) new_rank FROM @@ -42,26 +44,23 @@ async fn get_rework_scores( ) .bind(user_id) .bind(rework_id) - .fetch_all(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_all(ctx.database.get().await?.deref_mut()) + .await?; let mut scores: Vec = Vec::new(); for base_score in base_scores { - let beatmap: Beatmap = sqlx::query_as( - "SELECT beatmap_id, beatmapset_id, song_name FROM beatmaps WHERE beatmap_id = ?", - ) - .bind(base_score.beatmap_id) - .fetch_one(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + let beatmap: Beatmap = Beatmap { + beatmap_id: base_score.beatmap_id, + beatmapset_id: base_score.beatmapset_id, + song_name: base_score.song_name.clone(), + }; let score = APIReworkScore::from_base(base_score, beatmap); scores.push(score); } - match scores.is_empty() { + Ok(match scores.is_empty() { true => Json(None), false => Json(Some(scores)), - } + }) } diff --git a/src/api/routes/reworks/search.rs b/src/api/routes/reworks/search.rs index acbac95..12a8ed9 100644 --- a/src/api/routes/reworks/search.rs +++ b/src/api/routes/reworks/search.rs @@ -5,7 +5,7 @@ use axum::{ }; use std::{ops::DerefMut, sync::Arc}; -use crate::context::Context; +use crate::{api::error::AppResult, context::Context}; pub fn router() -> Router { Router::new().route("/api/v1/reworks/:rework_id/users/search", get(search_users)) @@ -26,7 +26,7 @@ async fn search_users( ctx: Extension>, Path(rework_id): Path, Query(query): Query, -) -> Json> { +) -> AppResult>> { let users: Vec = sqlx::query_as( "SELECT id user_id, username user_name FROM users WHERE username_safe LIKE ?", ) @@ -38,9 +38,8 @@ async fn search_users( .replace(" ", "_") .replace(|c: char| !c.is_ascii(), "") )) - .fetch_all(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_all(ctx.database.get().await?.deref_mut()) + .await?; let mut to_remove: Vec = Vec::new(); for user in &users { @@ -48,9 +47,8 @@ async fn search_users( sqlx::query_scalar("SELECT 1 FROM rework_stats WHERE user_id = ? AND rework_id = ?") .bind(user.user_id) .bind(rework_id) - .fetch_optional(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap() + .fetch_optional(ctx.database.get().await?.deref_mut()) + .await? .unwrap_or(false); if !in_rework { @@ -73,5 +71,5 @@ async fn search_users( .unwrap() }); - Json(users) + Ok(Json(users)) } diff --git a/src/api/routes/reworks/sessions.rs b/src/api/routes/reworks/sessions.rs index d7f9705..bbdd549 100644 --- a/src/api/routes/reworks/sessions.rs +++ b/src/api/routes/reworks/sessions.rs @@ -6,7 +6,7 @@ use axum::{ use std::sync::Arc; use crate::context::Context; -use crate::usecases; +use crate::{api::error::AppResult, usecases}; pub fn router() -> Router { Router::new() @@ -23,15 +23,17 @@ struct CreateSessionRequest { async fn create_session( Extension(ctx): Extension>, Json(request): Json, -) -> Json { +) -> AppResult> { let response = - usecases::sessions::create(request.username, request.password_md5, ctx.clone()).await; + usecases::sessions::create(request.username, request.password_md5, ctx.clone()).await?; - Json(response) + Ok(Json(response)) } -async fn delete_session(Extension(ctx): Extension>, Path(session): Path) { - let _ = usecases::sessions::delete(session, ctx.clone()) - .await - .unwrap(); +async fn delete_session( + Extension(ctx): Extension>, + Path(session): Path, +) -> AppResult<()> { + let _ = usecases::sessions::delete(session, ctx.clone()).await?; + Ok(()) } diff --git a/src/api/routes/reworks/user.rs b/src/api/routes/reworks/user.rs index 8bcb9b7..f06b74d 100644 --- a/src/api/routes/reworks/user.rs +++ b/src/api/routes/reworks/user.rs @@ -8,6 +8,7 @@ use axum::{ }; use crate::{ + api::error::AppResult, context::Context, models::{ rework::Rework, @@ -28,17 +29,16 @@ pub fn router() -> Router { async fn get_rework_user( ctx: Extension>, Path(user_id): Path, -) -> Json> { +) -> AppResult>> { let stats: Option<(String, String)> = sqlx::query_as( "SELECT users.username, country FROM users INNER JOIN users_stats USING(id) WHERE id = ?", ) .bind(user_id) - .fetch_optional(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_optional(ctx.database.get().await?.deref_mut()) + .await?; if stats.is_none() { - return Json(None); + return Ok(Json(None)); } let (user_name, country) = stats.unwrap(); @@ -46,9 +46,8 @@ async fn get_rework_user( let rework_stats: Vec = sqlx::query_as("SELECT * FROM rework_stats WHERE user_id = ?") .bind(user_id) - .fetch_all(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_all(ctx.database.get().await?.deref_mut()) + .await?; let rework_ids = rework_stats .iter() @@ -59,36 +58,34 @@ async fn get_rework_user( for rework_id in rework_ids { let rework: Rework = sqlx::query_as("SELECT * FROM reworks WHERE rework_id = ?") .bind(rework_id) - .fetch_one(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_one(ctx.database.get().await?.deref_mut()) + .await?; reworks.push(rework); } - Json(Some(ReworkUser { + Ok(Json(Some(ReworkUser { user_id, user_name, country, reworks, - })) + }))) } async fn get_rework_stats( ctx: Extension>, Path((rework_id, user_id)): Path<(i32, i32)>, -) -> Json> { +) -> AppResult>> { let stats: Option = sqlx::query_as( "SELECT user_id, rework_id, old_pp, new_pp FROM rework_stats WHERE user_id = ? AND rework_id = ?" ) .bind(user_id) .bind(rework_id) - .fetch_optional(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_optional(ctx.database.get().await?.deref_mut()) + .await?; if stats.is_none() { - return Json(None); + return Ok(Json(None)); } let stats = stats.unwrap(); @@ -97,17 +94,15 @@ async fn get_rework_stats( "SELECT users_stats.country, users.username FROM users_stats INNER JOIN users USING(id) WHERE users_stats.id = ?" ) .bind(user_id) - .fetch_one(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_one(ctx.database.get().await?.deref_mut()) + .await?; - let mut redis_connection = ctx.redis.get_async_connection().await.unwrap(); + let mut redis_connection = ctx.redis.get_async_connection().await?; let rework: Rework = sqlx::query_as("SELECT * FROM reworks WHERE rework_id = ?") .bind(rework_id) - .fetch_one(ctx.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_one(ctx.database.get().await?.deref_mut()) + .await?; let redis_leaderboard = match rework.rx { 0 => "leaderboard".to_string(), @@ -129,13 +124,11 @@ async fn get_rework_stats( format!("ripple:{}:{}", redis_leaderboard, stats_prefix), user_id, ) - .await - .unwrap(); + .await?; let new_rank_idx: Option = redis_connection .zrevrank(format!("rework:leaderboard:{}", rework.rework_id), user_id) - .await - .unwrap(); + .await?; let api_user = APIReworkStats::from_stats( stats, @@ -144,5 +137,5 @@ async fn get_rework_stats( (old_rank_idx.unwrap_or(-1) + 1) as u64, (new_rank_idx.unwrap_or(-1) + 1) as u64, ); - Json(Some(api_user)) + Ok(Json(Some(api_user))) } diff --git a/src/deploy/mod.rs b/src/deploy/mod.rs index 62a7560..74fa885 100644 --- a/src/deploy/mod.rs +++ b/src/deploy/mod.rs @@ -241,7 +241,7 @@ async fn recalculate_mode_scores( &format!( "SELECT s.id, s.beatmap_md5, s.userid, s.score, s.max_combo, s.full_combo, s.mods, s.300_count, s.100_count, s.50_count, s.katus_count, s.gekis_count, s.misses_count, s.time, s.play_mode, s.completed, - s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id + s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id, b.song_name FROM {} s INNER JOIN beatmaps b @@ -422,7 +422,7 @@ async fn recalculate_user( &format!( "SELECT s.id, s.beatmap_md5, s.userid, s.score, s.max_combo, s.full_combo, s.mods, s.300_count, s.100_count, s.50_count, s.katus_count, s.gekis_count, s.misses_count, s.time, s.play_mode, s.completed, - s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id + s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id, b.song_name FROM {} s INNER JOIN beatmaps b @@ -495,14 +495,12 @@ async fn recalculate_user( .bind(user_id) .bind(mode) .fetch_optional(ctx.database.get().await?.deref_mut()) - .await - .unwrap_or(None); + .await?; let inactive_days = match last_score_time { Some(time) => { ((SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() + .duration_since(SystemTime::UNIX_EPOCH)? .as_secs() as i32) - time) / 60 @@ -585,32 +583,32 @@ struct RecalculateContext { pub async fn serve(context: Context) -> anyhow::Result<()> { print!("Enter the modes (comma delimited) to deploy: "); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; let mut modes_str = String::new(); std::io::stdin().read_line(&mut modes_str)?; let modes = modes_str .trim() .split(',') - .map(|s| s.parse::().unwrap()) + .map(|s| s.parse::().expect("failed to parse mode")) .collect::>(); print!("\n"); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; print!("Enter the relax bits (comma delimited) to deploy: "); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; let mut relax_str = String::new(); std::io::stdin().read_line(&mut relax_str)?; let relax_bits = relax_str .trim() .split(',') - .map(|s| s.parse::().unwrap()) + .map(|s| s.parse::().expect("failed to parse relax bits")) .collect::>(); print!("\n"); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; let recalculate_context = Arc::new(Mutex::new(RecalculateContext { beatmaps: HashMap::new(), diff --git a/src/main.rs b/src/main.rs index 0f08d6c..9f8e60d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ async fn main() -> anyhow::Result<()> { .username(&config.database_username) .password(&config.database_password) .database(&config.database_name); - let database = DbPool::new(database_options, config.database_pool_max_size); + let database = DbPool::new(database_options, config.database_pool_max_size)?; let amqp_url = amqp_dsn( &config.amqp_username, diff --git a/src/mass_recalc/mod.rs b/src/mass_recalc/mod.rs index 52a6e82..44affbe 100644 --- a/src/mass_recalc/mod.rs +++ b/src/mass_recalc/mod.rs @@ -11,7 +11,7 @@ use crate::{ use lapin::{options::BasicPublishOptions, BasicProperties}; use redis::AsyncCommands; -async fn queue_user(user_id: i32, rework: &Rework, context: &Context) { +async fn queue_user(user_id: i32, rework: &Rework, context: &Context) -> anyhow::Result<()> { let scores_table = match rework.rx { 0 => "scores", 1 => "scores_relax", @@ -27,15 +27,13 @@ async fn queue_user(user_id: i32, rework: &Rework, context: &Context) { )) .bind(user_id) .bind(rework.mode) - .fetch_optional(context.database.get().await.unwrap().deref_mut()) - .await - .unwrap_or(None); + .fetch_optional(context.database.get().await?.deref_mut()) + .await?; let inactive_days = match last_score_time { Some(time) => { ((SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() + .duration_since(SystemTime::UNIX_EPOCH)? .as_secs() as i32) - time) / 60 @@ -46,7 +44,7 @@ async fn queue_user(user_id: i32, rework: &Rework, context: &Context) { }; if inactive_days >= 60 { - return; + return Ok(()); } let in_queue: Option = sqlx::query_scalar( @@ -55,20 +53,18 @@ async fn queue_user(user_id: i32, rework: &Rework, context: &Context) { .bind(user_id) .bind(rework.rework_id) .bind(rework.updated_at) - .fetch_optional(context.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_optional(context.database.get().await?.deref_mut()) + .await?; if in_queue.is_some() { - return; + return Ok(()); } sqlx::query(r#"REPLACE INTO rework_queue (user_id, rework_id) VALUES (?, ?)"#) .bind(user_id) .bind(rework.rework_id) - .execute(context.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .execute(context.database.get().await?.deref_mut()) + .await?; context .amqp_channel @@ -79,32 +75,31 @@ async fn queue_user(user_id: i32, rework: &Rework, context: &Context) { &rkyv::to_bytes::<_, 256>(&QueueRequest { user_id, rework_id: rework.rework_id, - }) - .unwrap(), + })?, BasicProperties::default(), ) - .await - .unwrap(); + .await?; log::info!("Queued user ID {}", user_id); + Ok(()) } pub async fn serve(context: Context) -> anyhow::Result<()> { print!("Enter a rework ID to mass recalculate: "); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; let mut rework_id_str = String::new(); std::io::stdin().read_line(&mut rework_id_str)?; let rework_id = rework_id_str.trim().parse::()?; print!("\n"); - std::io::stdout().flush().unwrap(); + std::io::stdout().flush()?; log::info!("Mass recalculating on rework ID {}", rework_id); let rework = usecases::reworks::fetch_one(rework_id, Arc::from(context.clone())) .await? - .unwrap(); + .expect("failed to find rework"); sqlx::query("DELETE FROM rework_scores WHERE rework_id = ?") .bind(rework_id) @@ -146,7 +141,7 @@ pub async fn serve(context: Context) -> anyhow::Result<()> { .await?; for (user_id,) in user_ids { - queue_user(user_id, &rework, &context).await; + queue_user(user_id, &rework, &context).await?; } Ok(()) diff --git a/src/models/pool.rs b/src/models/pool.rs index 40b7760..9f487ff 100644 --- a/src/models/pool.rs +++ b/src/models/pool.rs @@ -26,10 +26,7 @@ impl Manager for DbPool { type Pool = deadpool::managed::Pool; impl DbPool { - pub fn new(options: MySqlConnectOptions, max_size: usize) -> Pool { - Pool::builder(Self { options }) - .max_size(max_size) - .build() - .unwrap() + pub fn new(options: MySqlConnectOptions, max_size: usize) -> anyhow::Result { + Ok(Pool::builder(Self { options }).max_size(max_size).build()?) } } diff --git a/src/models/score.rs b/src/models/score.rs index 9c4adef..c207002 100644 --- a/src/models/score.rs +++ b/src/models/score.rs @@ -5,6 +5,7 @@ pub struct ReworkScore { pub score_id: i64, pub beatmap_id: i32, pub beatmapset_id: i32, + pub song_name: String, pub user_id: i32, pub rework_id: i32, pub max_combo: i32, @@ -27,6 +28,7 @@ impl ReworkScore { score_id: score.id, beatmap_id: score.beatmap_id, beatmapset_id: score.beatmapset_id, + song_name: score.song_name.clone(), user_id: score.userid, rework_id, max_combo: score.max_combo, @@ -50,6 +52,7 @@ pub struct APIBaseReworkScore { pub score_id: i64, pub beatmap_id: i32, pub beatmapset_id: i32, + pub song_name: String, pub user_id: i32, pub rework_id: i32, pub max_combo: i32, @@ -74,6 +77,7 @@ impl APIBaseReworkScore { score_id: score.score_id, beatmap_id: score.beatmap_id, beatmapset_id: score.beatmapset_id, + song_name: score.song_name, user_id: score.user_id, rework_id: score.rework_id, max_combo: score.max_combo, @@ -187,4 +191,5 @@ pub struct RippleScore { pub beatmap_id: i32, pub beatmapset_id: i32, + pub song_name: String, } diff --git a/src/processor/mod.rs b/src/processor/mod.rs index ed905a9..39de88e 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -24,8 +24,14 @@ use crate::{ usecases, }; -use conceptual_rework::{Beatmap as ConceptualBeatmap, BeatmapExt as ConceptualBeatmapExt, GameMode as ConceptualGameMode}; -use skill_rebalance::{Beatmap as SkillRebalanceBeatmap, BeatmapExt as SkillRebalanceBeatmapExt, GameMode as SkillRebalanceGameMode}; +use conceptual_rework::{ + Beatmap as ConceptualBeatmap, BeatmapExt as ConceptualBeatmapExt, + GameMode as ConceptualGameMode, +}; +use skill_rebalance::{ + Beatmap as SkillRebalanceBeatmap, BeatmapExt as SkillRebalanceBeatmapExt, + GameMode as SkillRebalanceGameMode, +}; fn round(x: f32, decimals: u32) -> f32 { let y = 10i32.pow(decimals) as f32; @@ -122,7 +128,7 @@ async fn process_scores( score, ) .await - }, + } 13 => { calculate_skill_rebalance_pp( Path::new(&context.config.beatmaps_path) @@ -161,10 +167,12 @@ async fn handle_queue_request( context: Arc, delivery_tag: u64, ) -> anyhow::Result<()> { - let rework = usecases::reworks::fetch_one(request.rework_id, context.clone()) - .await? - .unwrap(); + let rework = usecases::reworks::fetch_one(request.rework_id, context.clone()).await?; + if rework.is_none() { + anyhow::bail!("failed to find rework"); + } + let rework = rework.unwrap(); let scores_table = match rework.rx { 0 => "scores", 1 => "scores_relax", @@ -176,7 +184,7 @@ async fn handle_queue_request( &format!( "SELECT s.id, s.beatmap_md5, s.userid, s.score, s.max_combo, s.full_combo, s.mods, s.300_count, s.100_count, s.50_count, s.katus_count, s.gekis_count, s.misses_count, s.time, s.play_mode, s.completed, - s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id + s.accuracy, s.pp, s.checksum, s.patcher, s.pinned, b.beatmap_id, b.beatmapset_id, b.song_name FROM {} s INNER JOIN beatmaps b @@ -330,9 +338,8 @@ async fn rmq_listen(context: Arc) -> anyhow::Result<()> { if let Ok(delivery) = delivery { let deserialized_data: QueueRequest = rkyv::check_archived_root::(&delivery.data) - .unwrap() - .deserialize(&mut rkyv::Infallible) - .unwrap(); + .expect("failed to check archived root?") + .deserialize(&mut rkyv::Infallible)?; log::info!( "Received recalculation request for user ID {} on rework ID {}", diff --git a/src/repositories/leaderboards.rs b/src/repositories/leaderboards.rs index c0020e4..6855332 100644 --- a/src/repositories/leaderboards.rs +++ b/src/repositories/leaderboards.rs @@ -32,8 +32,7 @@ impl LeaderboardsRepository { sqlx::query_scalar("SELECT COUNT(*) FROM rework_stats WHERE rework_id = ?") .bind(rework.rework_id) .fetch_one(self.context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; let rework_users: Vec = sqlx::query_as( "SELECT user_id, users_stats.country, users.username user_name, rework_id, old_pp, new_pp, @@ -56,8 +55,7 @@ impl LeaderboardsRepository { .bind(offset) .bind(limit) .fetch_all(self.context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; let leaderboard = Leaderboard { total_count: leaderboard_count, diff --git a/src/repositories/sessions.rs b/src/repositories/sessions.rs index 59e114e..205a437 100644 --- a/src/repositories/sessions.rs +++ b/src/repositories/sessions.rs @@ -16,8 +16,7 @@ impl SessionsRepository { let mut redis_conn = self.context.redis.get_async_connection().await?; let mut session_token: Option = redis_conn .get(format!("rework:sessions:ids:{}", user_id)) - .await - .unwrap_or(None); + .await?; if session_token.is_none() { session_token = Some(Uuid::new_v4().to_string()); @@ -28,8 +27,7 @@ impl SessionsRepository { session_token.clone().unwrap(), 3600 * 2, // 2 hours ) - .await - .unwrap(); + .await?; let _: () = redis_conn .set_ex( @@ -37,8 +35,7 @@ impl SessionsRepository { user_id, 3600 * 2, // 2 hours ) - .await - .unwrap(); + .await?; } Ok(session_token.unwrap()) @@ -48,8 +45,7 @@ impl SessionsRepository { let mut connection = self.context.redis.get_async_connection().await?; let user_id: Option = connection .get(format!("rework:sessions:{}", session_token)) - .await - .unwrap(); + .await?; if user_id.is_none() { return Ok(()); @@ -59,13 +55,11 @@ impl SessionsRepository { let _: () = connection .del(format!("rework:sessions:{}", session_token)) - .await - .unwrap(); + .await?; let _: () = connection .del(format!("rework:sessions:ids:{}", user_id)) - .await - .unwrap(); + .await?; Ok(()) } diff --git a/src/usecases/sessions.rs b/src/usecases/sessions.rs index 688b171..cf503dd 100644 --- a/src/usecases/sessions.rs +++ b/src/usecases/sessions.rs @@ -19,41 +19,40 @@ pub async fn create( username: String, password_md5: String, context: Arc, -) -> CreateSessionResponse { +) -> anyhow::Result { let user_info: Option<(i32, String)> = sqlx::query_as("SELECT id, password_md5 FROM users WHERE username_safe = ?") .bind(&username.to_lowercase().replace(" ", "_")) - .fetch_optional(context.database.get().await.unwrap().deref_mut()) - .await - .unwrap(); + .fetch_optional(context.database.get().await?.deref_mut()) + .await?; if user_info.is_none() { - return CreateSessionResponse { + return Ok(CreateSessionResponse { success: false, user_id: None, session_token: None, - }; + }); } let (user_id, database_bcrypt) = user_info.unwrap(); - let correct_password = bcrypt::verify(&password_md5, &database_bcrypt).unwrap_or(false); + let correct_password = bcrypt::verify(&password_md5, &database_bcrypt)?; if !correct_password { - return CreateSessionResponse { + return Ok(CreateSessionResponse { success: false, user_id: None, session_token: None, - }; + }); } let repo = repositories::sessions::SessionsRepository::new(context); - let session_token = repo.create(user_id).await.unwrap(); + let session_token = repo.create(user_id).await?; - CreateSessionResponse { + Ok(CreateSessionResponse { success: true, user_id: Some(user_id), session_token: Some(session_token), - } + }) } pub async fn delete(session_token: String, context: Arc) -> anyhow::Result<()> { @@ -68,25 +67,25 @@ pub async fn enqueue( rework_id: i32, context: Arc, ) -> anyhow::Result { - let mut redis_conn = context.redis.get_async_connection().await.unwrap(); - let user_id: i32 = redis_conn + let mut redis_conn = context.redis.get_async_connection().await?; + let user_id: Option = redis_conn .get(format!("rework:sessions:{}", session_token)) - .await - .unwrap_or(0); + .await?; - if user_id == 0 { + if user_id.is_none() { return Ok(QueueResponse { success: false, message: Some("Invalid session token".to_string()), }); } + let user_id = user_id.unwrap(); + let user_privileges: Option<(i32,)> = sqlx::query_as(r#"SELECT privileges FROM users WHERE id = ?"#) .bind(user_id) .fetch_optional(context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; if user_privileges.is_none() { return Ok(QueueResponse { @@ -105,8 +104,7 @@ pub async fn enqueue( let rework: Rework = sqlx::query_as(r#"SELECT * FROM reworks WHERE rework_id = ?"#) .bind(rework_id) .fetch_one(context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; let in_queue: Option<(i32,)> = sqlx::query_as( r#"SELECT 1 FROM rework_queue WHERE user_id = ? AND rework_id = ? AND processed_at < ?"#, @@ -115,8 +113,7 @@ pub async fn enqueue( .bind(rework_id) .bind(rework.updated_at) .fetch_optional(context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; if in_queue.is_some() { return Ok(QueueResponse { @@ -129,8 +126,7 @@ pub async fn enqueue( .bind(user_id) .bind(rework_id) .execute(context.database.get().await?.deref_mut()) - .await - .unwrap(); + .await?; context .amqp_channel @@ -138,11 +134,10 @@ pub async fn enqueue( "", "rework_queue", BasicPublishOptions::default(), - &rkyv::to_bytes::<_, 256>(&QueueRequest { user_id, rework_id }).unwrap(), + &rkyv::to_bytes::<_, 256>(&QueueRequest { user_id, rework_id })?, BasicProperties::default(), ) - .await - .unwrap(); + .await?; Ok(QueueResponse { success: true, From 1d2806a08215d4860af66337783d546493b1040d Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Sun, 5 Nov 2023 19:41:29 +0000 Subject: [PATCH 05/17] feat: move beatmap files to s3 --- .env.example | 7 +- Cargo.lock | 307 ++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/api/routes/calculate.rs | 104 ++++-------- src/config.rs | 17 +- src/context.rs | 2 + src/deploy/mod.rs | 99 ++++-------- src/main.rs | 18 +++ src/processor/mod.rs | 75 +++------ src/usecases/beatmaps.rs | 28 ++++ src/usecases/mod.rs | 1 + 11 files changed, 446 insertions(+), 213 deletions(-) create mode 100644 src/usecases/beatmaps.rs diff --git a/.env.example b/.env.example index bbe8d53..9100363 100644 --- a/.env.example +++ b/.env.example @@ -17,6 +17,11 @@ REDIS_PORT=6379 REDIS_USERNAME= REDIS_PASSWORD= REDIS_DATABASE=0 -BEATMAPS_PATH= +REDIS_USE_SSL=false +AWS_REGION=ca-central-1 +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_ENDPOINT_URL= +AWS_BUCKET_NAME= SERVICE_READINESS_TIMEOUT=60 RUST_LOG=performance_service=info diff --git a/Cargo.lock b/Cargo.lock index f84d12e..08fcdd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" +[[package]] +name = "attohttpc" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" +dependencies = [ + "http", + "log", + "native-tls", + "serde", + "serde_json", + "url", +] + [[package]] name = "atty" version = "0.2.14" @@ -250,6 +264,32 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aws-creds" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3776743bb68d4ad02ba30ba8f64373f1be4e082fe47651767171ce75bb2f6cf5" +dependencies = [ + "attohttpc", + "dirs", + "log", + "quick-xml", + "rust-ini", + "serde", + "thiserror", + "time 0.3.26", + "url", +] + +[[package]] +name = "aws-region" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42fed2b9fca70f2908268d057a607f2a906f47edbf856ea8587de9038d264e22" +dependencies = [ + "thiserror", +] + [[package]] name = "axum" version = "0.3.4" @@ -257,7 +297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4e96976b2022b23b2199168ff9b281e9ddc1aa795607d5cb7146868ca5c101" dependencies = [ "async-trait", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", "http", @@ -315,6 +355,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "block-buffer" version = "0.10.4" @@ -429,7 +475,7 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -451,7 +497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", "indexmap", @@ -695,6 +741,15 @@ dependencies = [ "pem-rfc7468", ] +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "serde", +] + [[package]] name = "des" version = "0.8.1" @@ -715,6 +770,32 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + [[package]] name = "doc-comment" version = "0.3.3" @@ -1310,6 +1391,17 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "link-cplusplus" version = "1.0.8" @@ -1356,6 +1448,23 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9376a4f0340565ad675d11fc1419227faf5f60cd7ac9cb2e7185a471f30af833" +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.5.0" @@ -1368,6 +1477,15 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minidom" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f45614075738ce1b77a1768912a60c0227525971b03e09122a05b8a34a2a6278" +dependencies = [ + "rxml", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1495,7 +1613,7 @@ version = "0.10.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1534,6 +1652,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown", +] + [[package]] name = "os_str_bytes" version = "6.5.0" @@ -1593,7 +1721,7 @@ dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] @@ -1606,7 +1734,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "windows-sys 0.45.0", ] @@ -1656,6 +1784,7 @@ dependencies = [ "redis", "reqwest", "rkyv", + "rust-s3", "serde", "serde_json", "sqlx", @@ -1747,7 +1876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa" dependencies = [ "autocfg", - "bitflags", + "bitflags 1.3.2", "cfg-if", "concurrent-queue", "libc", @@ -1815,6 +1944,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "quick-xml" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.26" @@ -1900,7 +2039,27 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", ] [[package]] @@ -1958,10 +2117,12 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-util 0.7.7", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", "winreg", ] @@ -2032,13 +2193,56 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rust-s3" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b2ac5ff6acfbe74226fa701b5ef793aaa054055c13ebb7060ad36942956e027" +dependencies = [ + "async-trait", + "aws-creds", + "aws-region", + "base64 0.13.1", + "bytes", + "cfg-if", + "futures", + "hex", + "hmac", + "http", + "log", + "maybe-async", + "md5", + "minidom", + "percent-encoding", + "quick-xml", + "reqwest", + "serde", + "serde_derive", + "sha2", + "thiserror", + "time 0.3.26", + "tokio", + "tokio-stream", + "url", +] + [[package]] name = "rustix" version = "0.36.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.2.8", "io-lifetimes", "libc", @@ -2052,7 +2256,7 @@ version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.3.0", "io-lifetimes", "libc", @@ -2105,6 +2309,23 @@ dependencies = [ "base64 0.21.0", ] +[[package]] +name = "rxml" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98f186c7a2f3abbffb802984b7f1dfd65dac8be1aafdaabbca4137f53f0dff7" +dependencies = [ + "bytes", + "rxml_validation", + "smartstring", +] + +[[package]] +name = "rxml_validation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" + [[package]] name = "ryu" version = "1.0.13" @@ -2154,7 +2375,7 @@ version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2272,6 +2493,17 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "socket2" version = "0.4.9" @@ -2336,7 +2568,7 @@ checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ "ahash", "atoi", - "bitflags", + "bitflags 1.3.2", "byteorder", "bytes", "chrono", @@ -2406,6 +2638,12 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stringprep" version = "0.1.2" @@ -2476,7 +2714,7 @@ checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.2.16", "rustix 0.36.11", "windows-sys 0.42.0", ] @@ -2527,6 +2765,34 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c65469ed6b3a4809d987a41eb1dc918e9bc1d92211cbad7ae82931846f7451" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2672,7 +2938,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-util", @@ -2901,6 +3167,19 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.61" diff --git a/Cargo.toml b/Cargo.toml index b756bf4..845c4f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ reqwest = "0.11" conceptual-rework = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "conceptual-rework", features = ["async_tokio"] } async-trait = "0.1.62" skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "skill-rebalance", features = ["async_tokio"] } +rust-s3 = "0.33.0" [profile.release] lto = "fat" codegen-units = 1 diff --git a/src/api/routes/calculate.rs b/src/api/routes/calculate.rs index f7749c3..e9d8b4e 100644 --- a/src/api/routes/calculate.rs +++ b/src/api/routes/calculate.rs @@ -1,10 +1,8 @@ use crate::context::Context; +use crate::usecases; use akatsuki_pp_rs::{Beatmap, BeatmapExt, GameMode, PerformanceAttributes}; use axum::{extract::Extension, routing::post, Json, Router}; -use std::io::Cursor; -use std::path::{Path, PathBuf}; use std::sync::Arc; -use tokio::fs::File; pub fn router() -> Router { Router::new().route("/api/v1/calculate", post(calculate_play)) @@ -35,21 +33,12 @@ fn round(x: f32, decimals: u32) -> f32 { } async fn calculate_relax_pp( - beatmap_path: PathBuf, request: &CalculateRequest, -) -> CalculateResponse { - let beatmap = match Beatmap::from_path(beatmap_path).await { - Ok(beatmap) => beatmap, - Err(_) => { - return CalculateResponse { - stars: 0.0, - pp: 0.0, - ar: 0.0, - od: 0.0, - max_combo: 0, - } - } - }; + context: Arc, +) -> anyhow::Result { + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(request.beatmap_id, context).await?; + let beatmap = Beatmap::from_bytes(&beatmap_bytes).await?; let result = akatsuki_pp_rs::osu_2019::OsuPP::new(&beatmap) .mods(request.mods as u32) @@ -70,28 +59,22 @@ async fn calculate_relax_pp( stars = 0.0; } - CalculateResponse { + Ok(CalculateResponse { stars, pp, ar: result.difficulty.ar as f32, od: result.difficulty.od as f32, max_combo: result.difficulty.max_combo as i32, - } + }) } -async fn calculate_rosu_pp(beatmap_path: PathBuf, request: &CalculateRequest) -> CalculateResponse { - let beatmap = match Beatmap::from_path(beatmap_path).await { - Ok(beatmap) => beatmap, - Err(_) => { - return CalculateResponse { - stars: 0.0, - pp: 0.0, - ar: 0.0, - od: 0.0, - max_combo: 0, - } - } - }; +async fn calculate_rosu_pp( + request: &CalculateRequest, + context: Arc, +) -> anyhow::Result { + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(request.beatmap_id, context).await?; + let beatmap = Beatmap::from_bytes(&beatmap_bytes).await?; let result = beatmap .pp() @@ -120,7 +103,7 @@ async fn calculate_rosu_pp(beatmap_path: PathBuf, request: &CalculateRequest) -> stars = 0.0; } - match result { + Ok(match result { PerformanceAttributes::Osu(result) => CalculateResponse { stars, pp, @@ -149,23 +132,11 @@ async fn calculate_rosu_pp(beatmap_path: PathBuf, request: &CalculateRequest) -> od: 0.0, max_combo: result.difficulty.max_combo as i32, }, - } + }) } const RX: i32 = 1 << 7; -async fn download_beatmap(beatmap_path: PathBuf, request: &CalculateRequest) -> anyhow::Result<()> { - let response = reqwest::get(&format!("https://old.ppy.sh/osu/{}", request.beatmap_id)) - .await? - .error_for_status()?; - - let mut file = File::create(&beatmap_path).await?; - let mut content = Cursor::new(response.bytes().await?); - tokio::io::copy(&mut content, &mut file).await?; - - Ok(()) -} - async fn calculate_play( Extension(ctx): Extension>, Json(requests): Json>, @@ -173,34 +144,21 @@ async fn calculate_play( let mut results = Vec::new(); for request in requests { - let beatmap_path = - Path::new(&ctx.config.beatmaps_path).join(format!("{}.osu", request.beatmap_id)); - - if !beatmap_path.exists() { - match download_beatmap(beatmap_path.clone(), &request).await { - Ok(_) => {} - Err(_) => { - results.push(CalculateResponse { - stars: 0.0, - pp: 0.0, - ar: 0.0, - od: 0.0, - max_combo: 0, - }); - - log::warn!( - "Failed to download beatmap {} from 3rd party", - request.beatmap_id - ); - continue; - } - } - } - - let result = if request.mods & RX > 0 && request.mode == 0 { - calculate_relax_pp(beatmap_path, &request).await + let raw_result = if request.mods & RX > 0 && request.mode == 0 { + calculate_relax_pp(&request, ctx.clone()).await } else { - calculate_rosu_pp(beatmap_path, &request).await + calculate_rosu_pp(&request, ctx.clone()).await + }; + + let result = match raw_result { + Ok(result) => result, + Err(_) => CalculateResponse { + stars: 0.0, + pp: 0.0, + ar: 0.0, + od: 0.0, + max_combo: 0, + }, }; log::info!( diff --git a/src/config.rs b/src/config.rs index 46a90b6..6af8cb7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -58,5 +58,20 @@ pub struct Config { pub redis_database: i64, #[clap(long, env)] - pub beatmaps_path: String, + pub redis_use_ssl: bool, + + #[clap(long, env)] + pub aws_access_key_id: String, + + #[clap(long, env)] + pub aws_bucket_name: String, + + #[clap(long, env)] + pub aws_endpoint_url: String, + + #[clap(long, env)] + pub aws_region: String, + + #[clap(long, env)] + pub aws_secret_access_key: String, } diff --git a/src/context.rs b/src/context.rs index a26abf1..0a75e3c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,6 +1,7 @@ use deadpool::managed::Pool; use lapin::Channel; use redis::Client; +use s3::Bucket; use crate::{config::Config, models::pool::DbPool}; @@ -10,4 +11,5 @@ pub struct Context { pub database: Pool, pub amqp_channel: Channel, pub redis: Client, + pub bucket: Bucket, } diff --git a/src/deploy/mod.rs b/src/deploy/mod.rs index 74fa885..e2385b7 100644 --- a/src/deploy/mod.rs +++ b/src/deploy/mod.rs @@ -1,17 +1,9 @@ -use crate::{context::Context, models::score::RippleScore}; +use crate::{context::Context, models::score::RippleScore, usecases}; use akatsuki_pp_rs::{Beatmap, BeatmapExt, GameMode}; use redis::AsyncCommands; -use std::{ - collections::HashMap, - io::Cursor, - ops::DerefMut, - path::{Path, PathBuf}, - sync::Arc, - time::SystemTime, -}; +use std::{collections::HashMap, ops::DerefMut, sync::Arc, time::SystemTime}; use std::io::Write; -use tokio::fs::File; use tokio::sync::Mutex; #[derive(serde::Serialize, serde::Deserialize)] @@ -39,10 +31,10 @@ const RX: i32 = 1 << 7; const AP: i32 = 1 << 13; async fn calculate_special_pp( - beatmap_path: PathBuf, request: &CalculateRequest, + context: Arc, recalc_ctx: &Arc>, -) -> CalculateResponse { +) -> anyhow::Result { let mut recalc_mutex = recalc_ctx.lock().await; let beatmap = if recalc_mutex.beatmaps.contains_key(&request.beatmap_id) { @@ -52,21 +44,15 @@ async fn calculate_special_pp( .unwrap() .clone() } else { - match Beatmap::from_path(beatmap_path).await { - Ok(beatmap) => { - recalc_mutex - .beatmaps - .insert(request.beatmap_id, beatmap.clone()); + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(request.beatmap_id, context.clone()).await?; + let beatmap = Beatmap::from_bytes(&beatmap_bytes).await?; - beatmap - } - Err(_) => { - return CalculateResponse { - stars: 0.0, - pp: 0.0, - } - } - } + recalc_mutex + .beatmaps + .insert(request.beatmap_id, beatmap.clone()); + + beatmap }; drop(recalc_mutex); @@ -88,14 +74,14 @@ async fn calculate_special_pp( stars = 0.0; } - CalculateResponse { stars, pp } + Ok(CalculateResponse { stars, pp }) } async fn calculate_rosu_pp( - beatmap_path: PathBuf, request: &CalculateRequest, + context: Arc, recalc_ctx: &Arc>, -) -> CalculateResponse { +) -> anyhow::Result { let mut recalc_mutex = recalc_ctx.lock().await; let beatmap = if recalc_mutex.beatmaps.contains_key(&request.beatmap_id) { @@ -105,21 +91,15 @@ async fn calculate_rosu_pp( .unwrap() .clone() } else { - match Beatmap::from_path(beatmap_path).await { - Ok(beatmap) => { - recalc_mutex - .beatmaps - .insert(request.beatmap_id, beatmap.clone()); + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(request.beatmap_id, context.clone()).await?; + let beatmap = Beatmap::from_bytes(&beatmap_bytes).await?; - beatmap - } - Err(_) => { - return CalculateResponse { - stars: 0.0, - pp: 0.0, - } - } - } + recalc_mutex + .beatmaps + .insert(request.beatmap_id, beatmap.clone()); + + beatmap }; drop(recalc_mutex); @@ -149,12 +129,11 @@ async fn calculate_rosu_pp( stars = 0.0; } - CalculateResponse { stars, pp } + Ok(CalculateResponse { stars, pp }) } async fn recalculate_score( score: RippleScore, - beatmap_path: PathBuf, ctx: Arc, recalc_ctx: Arc>, ) -> anyhow::Result<()> { @@ -168,9 +147,9 @@ async fn recalculate_score( }; let response = if score.mods & RX > 0 && score.play_mode == 0 { - calculate_special_pp(beatmap_path, &request, &recalc_ctx).await + calculate_special_pp(&request, ctx.clone(), &recalc_ctx).await? } else { - calculate_rosu_pp(beatmap_path, &request, &recalc_ctx).await + calculate_rosu_pp(&request, ctx.clone(), &recalc_ctx).await? }; let rx = if score.mods & RX > 0 { @@ -261,31 +240,7 @@ async fn recalculate_mode_scores( let mut futures = Vec::new(); for score in score_chunk { - let beatmap_path = - Path::new(&ctx.config.beatmaps_path).join(format!("{}.osu", score.beatmap_id)); - - if !beatmap_path.exists() { - log::info!( - "Beatmap {} doesn't exist, fetching from bancho", - score.beatmap_id - ); - - let response = - reqwest::get(&format!("https://old.ppy.sh/osu/{}", score.beatmap_id)) - .await? - .error_for_status()?; - - let mut file = File::create(&beatmap_path).await?; - let mut content = Cursor::new(response.bytes().await?); - tokio::io::copy(&mut content, &mut file).await?; - } - - let future = tokio::spawn(recalculate_score( - score, - beatmap_path, - ctx.clone(), - recalc_ctx.clone(), - )); + let future = tokio::spawn(recalculate_score(score, ctx.clone(), recalc_ctx.clone())); futures.push(future); } diff --git a/src/main.rs b/src/main.rs index 9f8e60d..1d0e360 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use performance_service::{ api, config::Config, context::Context, deploy, mass_recalc, models::pool::DbPool, processor, }; use redis::{Client, ConnectionAddr, ConnectionInfo, RedisConnectionInfo}; +use s3::{creds::Credentials, Bucket, Region}; use sqlx::mysql::MySqlConnectOptions; fn amqp_dsn(username: &str, password: &str, host: &str, port: u16) -> String { @@ -48,11 +49,28 @@ async fn main() -> anyhow::Result<()> { }; let redis = Client::open(redis_connection_options)?; + let custom_region = Region::Custom { + region: config.aws_region.clone(), + endpoint: config.aws_endpoint_url.clone(), + }; + let bucket = Bucket::new( + &config.aws_bucket_name, + custom_region, + Credentials { + access_key: Some(config.aws_access_key_id.clone()), + secret_key: Some(config.aws_secret_access_key.clone()), + security_token: None, + session_token: None, + expiration: None, + }, + )?; + let context = Context { config, database, amqp_channel, redis, + bucket, }; match context.config.app_component.as_str() { diff --git a/src/processor/mod.rs b/src/processor/mod.rs index 39de88e..cdb49a6 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -1,9 +1,4 @@ -use std::{ - ops::DerefMut, - path::{Path, PathBuf}, - sync::Arc, - time::Duration, -}; +use std::{ops::DerefMut, sync::Arc, time::Duration}; use lapin::{ options::{BasicAckOptions, BasicConsumeOptions, QueueDeclareOptions}, @@ -38,11 +33,13 @@ fn round(x: f32, decimals: u32) -> f32 { (x * y).round() / y } -async fn calculate_conceptual_pp(beatmap_path: PathBuf, score: &RippleScore) -> f32 { - let beatmap = match ConceptualBeatmap::from_path(beatmap_path).await { - Ok(beatmap) => beatmap, - Err(_) => return 0.0, - }; +async fn calculate_conceptual_pp( + score: &RippleScore, + context: Arc, +) -> anyhow::Result { + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(score.beatmap_id, context).await?; + let beatmap = ConceptualBeatmap::from_bytes(&beatmap_bytes).await?; let result = beatmap .pp() @@ -64,14 +61,16 @@ async fn calculate_conceptual_pp(beatmap_path: PathBuf, score: &RippleScore) -> pp = 0.0; } - pp + Ok(pp) } -async fn calculate_skill_rebalance_pp(beatmap_path: PathBuf, score: &RippleScore) -> f32 { - let beatmap = match SkillRebalanceBeatmap::from_path(beatmap_path).await { - Ok(beatmap) => beatmap, - Err(_) => return 0.0, - }; +async fn calculate_skill_rebalance_pp( + score: &RippleScore, + context: Arc, +) -> anyhow::Result { + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(score.beatmap_id, context).await?; + let beatmap = SkillRebalanceBeatmap::from_bytes(&beatmap_bytes).await?; let result = beatmap .pp() @@ -93,50 +92,22 @@ async fn calculate_skill_rebalance_pp(beatmap_path: PathBuf, score: &RippleScore pp = 0.0; } - pp + Ok(pp) } async fn process_scores( rework: &Rework, scores: Vec, - context: &Arc, + context: Arc, ) -> anyhow::Result> { let mut rework_scores: Vec = Vec::new(); for score in &scores { let new_pp = match rework.rework_id { - 10 => { - calculate_conceptual_pp( - Path::new(&context.config.beatmaps_path) - .join(format!("{}.osu", score.beatmap_id)), - score, - ) - .await - } - 11 => { - calculate_conceptual_pp( - Path::new(&context.config.beatmaps_path) - .join(format!("{}.osu", score.beatmap_id)), - score, - ) - .await - } - 12 => { - calculate_conceptual_pp( - Path::new(&context.config.beatmaps_path) - .join(format!("{}.osu", score.beatmap_id)), - score, - ) - .await - } - 13 => { - calculate_skill_rebalance_pp( - Path::new(&context.config.beatmaps_path) - .join(format!("{}.osu", score.beatmap_id)), - score, - ) - .await - } + 10 => calculate_conceptual_pp(score, context.clone()).await?, + 11 => calculate_conceptual_pp(score, context.clone()).await?, + 12 => calculate_conceptual_pp(score, context.clone()).await?, + 13 => calculate_skill_rebalance_pp(score, context.clone()).await?, _ => unreachable!(), }; @@ -215,7 +186,7 @@ async fn handle_queue_request( .fetch_one(context.database.get().await?.deref_mut()) .await?; - let rework_scores = process_scores(&rework, scores, &context).await?; + let rework_scores = process_scores(&rework, scores, context.clone()).await?; let new_pp = calculate_new_pp(&rework_scores, score_count); for rework_score in rework_scores { diff --git a/src/usecases/beatmaps.rs b/src/usecases/beatmaps.rs new file mode 100644 index 0000000..75d2752 --- /dev/null +++ b/src/usecases/beatmaps.rs @@ -0,0 +1,28 @@ +use std::sync::Arc; + +use crate::context::Context; + +pub async fn fetch_beatmap_osu_file( + beatmap_id: i32, + context: Arc, +) -> anyhow::Result> { + let beatmap_path = &format!("beatmaps/{beatmap_id}.osu"); + + let existing_file = context.bucket.get_object(beatmap_path).await?; + if existing_file.status_code() == 200 { + return Ok(existing_file.as_slice().to_vec()); + } + + let osu_response = reqwest::get(&format!("https://old.ppy.sh/osu/{beatmap_id}")) + .await? + .error_for_status()?; + + let response_bytes = osu_response.bytes().await?.to_vec(); + + context + .bucket + .put_object(beatmap_path, &response_bytes) + .await?; + + Ok(response_bytes) +} diff --git a/src/usecases/mod.rs b/src/usecases/mod.rs index 17b7efb..c8b676e 100644 --- a/src/usecases/mod.rs +++ b/src/usecases/mod.rs @@ -1,3 +1,4 @@ +pub mod beatmaps; pub mod leaderboards; pub mod reworks; pub mod sessions; From 3e7fc560268be675ddea97251063e61f6e7d0a6a Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Sun, 5 Nov 2023 20:09:35 +0000 Subject: [PATCH 06/17] feat: massively speed up docker speeds --- .dockerignore | 3 ++- Cargo.toml | 4 +++- Dockerfile | 27 +++++++++++++++++---------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.dockerignore b/.dockerignore index a90d171..3ba51c6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .env* .pre-commit-config.yaml -*.example \ No newline at end of file +*.example +target/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 845c4f2..3acc00a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,9 @@ conceptual-rework = { package = "akatsuki-pp", git = "https://github.com/osuAkat async-trait = "0.1.62" skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "skill-rebalance", features = ["async_tokio"] } rust-s3 = "0.33.0" + [profile.release] lto = "fat" -codegen-units = 1 +codegen-units = 16 +opt-level = 3 panic = "abort" diff --git a/Dockerfile b/Dockerfile index 306efdb..5ee38bc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,22 @@ -FROM lukemathwalker/cargo-chef:latest-rust-bookworm AS chef +# syntax=docker/dockerfile:1.3-labs + +FROM rust:latest AS build + +RUN cargo new --lib /performance-service +COPY Cargo.toml Cargo.lock /performance-service/ + WORKDIR /performance-service +RUN --mount=type=cache,target=/usr/local/cargo/registry cargo build --release + +COPY . /performance-service -FROM chef AS prepare -COPY . . -RUN cargo chef prepare --recipe-path recipe.json +RUN --mount=type=cache,target=/usr/local/cargo/registry < Date: Sun, 5 Nov 2023 20:27:05 +0000 Subject: [PATCH 07/17] fix: display reason for performance calc failure --- src/api/routes/calculate.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/api/routes/calculate.rs b/src/api/routes/calculate.rs index e9d8b4e..328960d 100644 --- a/src/api/routes/calculate.rs +++ b/src/api/routes/calculate.rs @@ -152,13 +152,21 @@ async fn calculate_play( let result = match raw_result { Ok(result) => result, - Err(_) => CalculateResponse { - stars: 0.0, - pp: 0.0, - ar: 0.0, - od: 0.0, - max_combo: 0, - }, + Err(e) => { + log::error!( + "Performance calculation failed for beatmap {}: {}", + request.beatmap_id, + e.to_string() + ); + + CalculateResponse { + stars: 0.0, + pp: 0.0, + ar: 0.0, + od: 0.0, + max_combo: 0, + } + } }; log::info!( From 5528a5464f812bc1170be36dcbeebb5d25f29203 Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Sun, 5 Nov 2023 20:43:01 +0000 Subject: [PATCH 08/17] fix: handle 404 gracefully --- src/usecases/beatmaps.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/usecases/beatmaps.rs b/src/usecases/beatmaps.rs index 75d2752..ca212ec 100644 --- a/src/usecases/beatmaps.rs +++ b/src/usecases/beatmaps.rs @@ -1,5 +1,7 @@ use std::sync::Arc; +use s3::error::S3Error; + use crate::context::Context; pub async fn fetch_beatmap_osu_file( @@ -8,9 +10,13 @@ pub async fn fetch_beatmap_osu_file( ) -> anyhow::Result> { let beatmap_path = &format!("beatmaps/{beatmap_id}.osu"); - let existing_file = context.bucket.get_object(beatmap_path).await?; - if existing_file.status_code() == 200 { - return Ok(existing_file.as_slice().to_vec()); + let existing_file = match context.bucket.get_object(beatmap_path).await { + Ok(existing_file) => Ok(Some(existing_file)), + Err(S3Error::Http(status_code, _)) if status_code == 404 => Ok(None), + Err(e) => Err(e), + }?; + if existing_file.is_some() { + return Ok(existing_file.unwrap().to_vec()); } let osu_response = reqwest::get(&format!("https://old.ppy.sh/osu/{beatmap_id}")) From 5ae5a7efbaeb63864a308f88ab53e0133438eceb Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 14:12:05 +0000 Subject: [PATCH 09/17] add the rework --- Cargo.lock | 9 +++++++++ Cargo.toml | 21 +++++++++++++++++---- src/processor/mod.rs | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08fcdd2..7b0cd85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,14 @@ dependencies = [ "tokio", ] +[[package]] +name = "akatsuki-pp" +version = "0.9.4" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=the#eb2d905b36e40c6d81d012e8255f99276b65eed1" +dependencies = [ + "tokio", +] + [[package]] name = "akatsuki-pp" version = "0.9.4" @@ -1766,6 +1774,7 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=the)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 3acc00a..ef73561 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,11 @@ tower = "0.4.11" tower-http = { version = "0.2.0", features = ["trace"] } axum = { version = "0.3.4", features = ["tower-log"] } chrono = { version = "0.4.22", features = ["serde"] } -sqlx = { version = "0.6.2", features = ["runtime-tokio-native-tls", "mysql", "chrono"] } +sqlx = { version = "0.6.2", features = [ + "runtime-tokio-native-tls", + "mysql", + "chrono", +] } lapin = "2.1.1" deadpool = { version = "0.9.5", features = ["rt_tokio_1"] } deadpool-lapin = "0.10.0" @@ -34,12 +38,21 @@ bcrypt = "0.13.0" uuid = { version = "1.2.1", features = ["v4"] } futures = "0.3.17" strsim = "0.10.0" -akatsuki-pp-rs = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "764da0dbf42ed80441acf99d070aaedabaed4b75", features = ["async_tokio"] } +akatsuki-pp-rs = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "764da0dbf42ed80441acf99d070aaedabaed4b75", features = [ + "async_tokio", +] } reqwest = "0.11" -conceptual-rework = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "conceptual-rework", features = ["async_tokio"] } +conceptual-rework = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "conceptual-rework", features = [ + "async_tokio", +] } async-trait = "0.1.62" -skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "skill-rebalance", features = ["async_tokio"] } +skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "skill-rebalance", features = [ + "async_tokio", +] } rust-s3 = "0.33.0" +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "the", features = [ + "async_tokio", +] } [profile.release] lto = "fat" diff --git a/src/processor/mod.rs b/src/processor/mod.rs index cdb49a6..9e5c9d5 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -27,6 +27,7 @@ use skill_rebalance::{ Beatmap as SkillRebalanceBeatmap, BeatmapExt as SkillRebalanceBeatmapExt, GameMode as SkillRebalanceGameMode, }; +use the::Beatmap as TheBeatmap; fn round(x: f32, decimals: u32) -> f32 { let y = 10i32.pow(decimals) as f32; @@ -95,6 +96,26 @@ async fn calculate_skill_rebalance_pp( Ok(pp) } +async fn calculate_the_pp(score: &RippleScore, context: Arc) -> anyhow::Result { + let beatmap_bytes = + usecases::beatmaps::fetch_beatmap_osu_file(score.beatmap_id, context).await?; + let beatmap = TheBeatmap::from_bytes(&beatmap_bytes).await?; + + let result = the::osu_2019::OsuPP::new(&beatmap) + .mods(score.mods as u32) + .combo(score.max_combo as usize) + .misses(score.count_misses as usize) + .accuracy(score.accuracy) + .calculate(); + + let mut pp = round(result.pp as f32, 2); + if pp.is_infinite() || pp.is_nan() { + pp = 0.0; + } + + Ok(pp) +} + async fn process_scores( rework: &Rework, scores: Vec, @@ -108,6 +129,7 @@ async fn process_scores( 11 => calculate_conceptual_pp(score, context.clone()).await?, 12 => calculate_conceptual_pp(score, context.clone()).await?, 13 => calculate_skill_rebalance_pp(score, context.clone()).await?, + 14 => calculate_the_pp(score, context.clone()).await?, _ => unreachable!(), }; From e8a931b1a0653992cb9e33a8fa47e4ea3f641d7e Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 14:31:24 +0000 Subject: [PATCH 10/17] move the to rev-based --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b0cd85..e819b32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=the#eb2d905b36e40c6d81d012e8255f99276b65eed1" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=0e07a33c836ffc248559733f80715b941ed0db4b#0e07a33c836ffc248559733f80715b941ed0db4b" dependencies = [ "tokio", ] @@ -1774,7 +1774,7 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=the)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=0e07a33c836ffc248559733f80715b941ed0db4b)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index ef73561..3e08ef0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", branch = "the", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "0e07a33c836ffc248559733f80715b941ed0db4b", features = [ "async_tokio", ] } From 864a7a58ad5ca469f20eb8a23074ba4c187d12fc Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 14:45:13 +0000 Subject: [PATCH 11/17] bump the --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e819b32..8d3d007 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=0e07a33c836ffc248559733f80715b941ed0db4b#0e07a33c836ffc248559733f80715b941ed0db4b" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4311fb4b4c735c1b1663959b067dfe7e28e46b61#4311fb4b4c735c1b1663959b067dfe7e28e46b61" dependencies = [ "tokio", ] @@ -1774,7 +1774,7 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=0e07a33c836ffc248559733f80715b941ed0db4b)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4311fb4b4c735c1b1663959b067dfe7e28e46b61)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 3e08ef0..2937391 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "0e07a33c836ffc248559733f80715b941ed0db4b", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "4311fb4b4c735c1b1663959b067dfe7e28e46b61", features = [ "async_tokio", ] } From ad2e0319b4f618aeac0a410039bb5169c8be8688 Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 14:51:00 +0000 Subject: [PATCH 12/17] replace panic with log --- src/processor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/mod.rs b/src/processor/mod.rs index 9e5c9d5..7b3d1f5 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -350,7 +350,7 @@ async fn rmq_listen(context: Arc) -> anyhow::Result<()> { .await; if result.is_err() { - panic!("Error processing queue request: {:?}", result); + log::error!("Error processing queue request: {:?}", result); } }); } From 1de4f624d303b9b8de7a69dbb39a9ac9ae20a1b3 Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 15:03:31 +0000 Subject: [PATCH 13/17] bump --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d3d007..f2fe805 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4311fb4b4c735c1b1663959b067dfe7e28e46b61#4311fb4b4c735c1b1663959b067dfe7e28e46b61" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" dependencies = [ "tokio", ] @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e#fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e" dependencies = [ "tokio", ] @@ -1774,8 +1774,8 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4311fb4b4c735c1b1663959b067dfe7e28e46b61)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e)", "anyhow", "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index 2937391..d0009e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "4311fb4b4c735c1b1663959b067dfe7e28e46b61", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e", features = [ "async_tokio", ] } From 8ab6564ed73c1014bcf988e01f465c15a7d2ff5e Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 15:11:41 +0000 Subject: [PATCH 14/17] bump --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2fe805..6480eef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=6c4392075fe044353972e35d184c8a4f3604b1d0#6c4392075fe044353972e35d184c8a4f3604b1d0" dependencies = [ "tokio", ] @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e#fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" dependencies = [ "tokio", ] @@ -1774,8 +1774,8 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=6c4392075fe044353972e35d184c8a4f3604b1d0)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e)", "anyhow", "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index d0009e9..37967f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "fbc9e3c3ec1673047840c0c86f8fe34e71d9fd0e", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "6c4392075fe044353972e35d184c8a4f3604b1d0", features = [ "async_tokio", ] } From 480fa6ec542fd536c0cdcf202be495165293b052 Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 15:35:45 +0000 Subject: [PATCH 15/17] bump --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6480eef..8f9dc9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=6c4392075fe044353972e35d184c8a4f3604b1d0#6c4392075fe044353972e35d184c8a4f3604b1d0" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=3f1f73b18a3b0deb51136c19212e11e807fbc1f4#3f1f73b18a3b0deb51136c19212e11e807fbc1f4" dependencies = [ "tokio", ] @@ -1774,7 +1774,7 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=6c4392075fe044353972e35d184c8a4f3604b1d0)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=3f1f73b18a3b0deb51136c19212e11e807fbc1f4)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 37967f6..c9be1e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "6c4392075fe044353972e35d184c8a4f3604b1d0", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "3f1f73b18a3b0deb51136c19212e11e807fbc1f4", features = [ "async_tokio", ] } From b4c07b0aa83cfa9e6ec84bd1dc0d8bedf502b99d Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 15:42:45 +0000 Subject: [PATCH 16/17] bump --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f9dc9f..26e6b63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=3f1f73b18a3b0deb51136c19212e11e807fbc1f4#3f1f73b18a3b0deb51136c19212e11e807fbc1f4" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" dependencies = [ "tokio", ] @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbe3d994299bfe07fd4de70f9e37ed9b91853ced#fbe3d994299bfe07fd4de70f9e37ed9b91853ced" dependencies = [ "tokio", ] @@ -1774,8 +1774,8 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=3f1f73b18a3b0deb51136c19212e11e807fbc1f4)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbe3d994299bfe07fd4de70f9e37ed9b91853ced)", "anyhow", "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index c9be1e8..7c06718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "3f1f73b18a3b0deb51136c19212e11e807fbc1f4", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "fbe3d994299bfe07fd4de70f9e37ed9b91853ced", features = [ "async_tokio", ] } From 96000e891f43c2facf99c787d78962b8c672426d Mon Sep 17 00:00:00 2001 From: tsunyoku Date: Thu, 16 Nov 2023 15:50:19 +0000 Subject: [PATCH 17/17] bump --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26e6b63..acf44e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4ae182f4f294e6ac34eca1dc2e5f676748c4fd76#4ae182f4f294e6ac34eca1dc2e5f676748c4fd76" dependencies = [ "tokio", ] @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "akatsuki-pp" version = "0.9.4" -source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbe3d994299bfe07fd4de70f9e37ed9b91853ced#fbe3d994299bfe07fd4de70f9e37ed9b91853ced" +source = "git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75#764da0dbf42ed80441acf99d070aaedabaed4b75" dependencies = [ "tokio", ] @@ -1774,8 +1774,8 @@ version = "0.1.0" dependencies = [ "akatsuki-pp 0.9.3", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?branch=skill-rebalance)", + "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=4ae182f4f294e6ac34eca1dc2e5f676748c4fd76)", "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=764da0dbf42ed80441acf99d070aaedabaed4b75)", - "akatsuki-pp 0.9.4 (git+https://github.com/osuAkatsuki/akatsuki-pp-rs?rev=fbe3d994299bfe07fd4de70f9e37ed9b91853ced)", "anyhow", "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index 7c06718..b936244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ skill-rebalance = { package = "akatsuki-pp", git = "https://github.com/osuAkatsu "async_tokio", ] } rust-s3 = "0.33.0" -the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "fbe3d994299bfe07fd4de70f9e37ed9b91853ced", features = [ +the = { package = "akatsuki-pp", git = "https://github.com/osuAkatsuki/akatsuki-pp-rs", rev = "4ae182f4f294e6ac34eca1dc2e5f676748c4fd76", features = [ "async_tokio", ] }