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
This commit is contained in:
aecsocket
2026-02-05 05:18:33 +00:00
committed by GitHub
parent 9105a68923
commit b1954be2c7
5 changed files with 16 additions and 32 deletions

View File

@@ -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"
}

View File

@@ -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<String, util::CacheSubscriber>,
meta_namespace: String,
cache_list: Arc<DashMap<String, util::CacheSubscriber>>,
meta_namespace: Arc<str>,
}
pub struct RedisConnection {
pub connection: deadpool_redis::Connection,
meta_namespace: String,
meta_namespace: Arc<str>,
}
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<String>) -> Self {
pub fn new(meta_namespace: impl Into<Arc<str>>) -> 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")

View File

@@ -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());

View File

@@ -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
)

View File

@@ -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 =