From b1954be2c72518df87b610cb947e239297753f0d Mon Sep 17 00:00:00 2001 From: aecsocket Date: Thu, 5 Feb 2026 05:18:33 +0000 Subject: [PATCH] Ref-count Redis pool internals, fix project creation slug/ID collision (#5302) * Ref-count Redis pool internals, fix project creation slug/ID collision * cargo sqlx prepare --- ...696062009c5f681baaf29dfc24cfbbda93742.json | 22 ------------------- apps/labrinth/src/database/redis/mod.rs | 13 ++++++----- apps/labrinth/src/main.rs | 2 +- .../src/routes/v3/project_creation.rs | 7 +++++- apps/labrinth/src/test/database.rs | 4 ++-- 5 files changed, 16 insertions(+), 32 deletions(-) delete mode 100644 apps/labrinth/.sqlx/query-f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742.json diff --git a/apps/labrinth/.sqlx/query-f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742.json b/apps/labrinth/.sqlx/query-f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742.json deleted file mode 100644 index c398d97d7..000000000 --- a/apps/labrinth/.sqlx/query-f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT EXISTS(SELECT 1 FROM mods WHERE slug = LOWER($1))\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742" -} diff --git a/apps/labrinth/src/database/redis/mod.rs b/apps/labrinth/src/database/redis/mod.rs index bd84f6716..da2f336ed 100644 --- a/apps/labrinth/src/database/redis/mod.rs +++ b/apps/labrinth/src/database/redis/mod.rs @@ -14,6 +14,7 @@ use std::collections::HashMap; use std::fmt::{Debug, Display}; use std::future::Future; use std::hash::Hash; +use std::sync::Arc; use std::time::Duration; use tracing::{Instrument, info, info_span}; use util::{cmd, redis_pipe}; @@ -27,20 +28,20 @@ const ACTUAL_EXPIRY: i64 = 60 * 30; // 30 minutes pub struct RedisPool { pub url: String, pub pool: deadpool_redis::Pool, - cache_list: DashMap, - meta_namespace: String, + cache_list: Arc>, + meta_namespace: Arc, } pub struct RedisConnection { pub connection: deadpool_redis::Connection, - meta_namespace: String, + meta_namespace: Arc, } impl RedisPool { // initiate a new redis pool // testing pool uses a hashmap to mimic redis behaviour for very small data sizes (ie: tests) // PANICS: production pool will panic if redis url is not set - pub fn new(meta_namespace: Option) -> Self { + pub fn new(meta_namespace: impl Into>) -> Self { let wait_timeout = dotenvy::var("REDIS_WAIT_TIMEOUT_MS").ok().map_or_else( || Duration::from_millis(15000), @@ -71,8 +72,8 @@ impl RedisPool { let pool = RedisPool { url, pool, - cache_list: DashMap::with_capacity(2048), - meta_namespace: meta_namespace.unwrap_or("".to_string()), + cache_list: Arc::new(DashMap::with_capacity(2048)), + meta_namespace: meta_namespace.into(), }; let redis_min_connections = dotenvy::var("REDIS_MIN_CONNECTIONS") diff --git a/apps/labrinth/src/main.rs b/apps/labrinth/src/main.rs index 4b2192ac8..4763a7af4 100644 --- a/apps/labrinth/src/main.rs +++ b/apps/labrinth/src/main.rs @@ -117,7 +117,7 @@ async fn app() -> std::io::Result<()> { .expect("Database connection failed"); // Redis connector - let redis_pool = RedisPool::new(None); + let redis_pool = RedisPool::new(""); let storage_backend = dotenvy::var("STORAGE_BACKEND").unwrap_or_else(|_| "local".to_string()); diff --git a/apps/labrinth/src/routes/v3/project_creation.rs b/apps/labrinth/src/routes/v3/project_creation.rs index c20619085..1071c124d 100644 --- a/apps/labrinth/src/routes/v3/project_creation.rs +++ b/apps/labrinth/src/routes/v3/project_creation.rs @@ -497,7 +497,12 @@ async fn project_create_inner( { let results = sqlx::query!( " - SELECT EXISTS(SELECT 1 FROM mods WHERE slug = LOWER($1)) + SELECT EXISTS( + SELECT 1 FROM mods + WHERE + slug = LOWER($1) + OR text_id_lower = LOWER($1) + ) ", create_data.slug ) diff --git a/apps/labrinth/src/test/database.rs b/apps/labrinth/src/test/database.rs index ea6df5570..02b6f556f 100644 --- a/apps/labrinth/src/test/database.rs +++ b/apps/labrinth/src/test/database.rs @@ -89,7 +89,7 @@ impl TemporaryDatabase { println!("Migrations complete"); // Gets new Redis pool - let redis_pool = RedisPool::new(Some(temp_database_name.clone())); + let redis_pool = RedisPool::new(temp_database_name.clone()); // Create new meilisearch config let search_config = @@ -194,7 +194,7 @@ impl TemporaryDatabase { pool: pool.clone(), ro_pool: ReadOnlyPgPool::from(pool.clone()), database_name: TEMPLATE_DATABASE_NAME.to_string(), - redis_pool: RedisPool::new(Some(name.clone())), + redis_pool: RedisPool::new(name.clone()), search_config: search::SearchConfig::new(Some(name)), }; let setup_api =