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:
@@ -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"
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,7 @@ use std::collections::HashMap;
|
|||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{Instrument, info, info_span};
|
use tracing::{Instrument, info, info_span};
|
||||||
use util::{cmd, redis_pipe};
|
use util::{cmd, redis_pipe};
|
||||||
@@ -27,20 +28,20 @@ const ACTUAL_EXPIRY: i64 = 60 * 30; // 30 minutes
|
|||||||
pub struct RedisPool {
|
pub struct RedisPool {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub pool: deadpool_redis::Pool,
|
pub pool: deadpool_redis::Pool,
|
||||||
cache_list: DashMap<String, util::CacheSubscriber>,
|
cache_list: Arc<DashMap<String, util::CacheSubscriber>>,
|
||||||
meta_namespace: String,
|
meta_namespace: Arc<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RedisConnection {
|
pub struct RedisConnection {
|
||||||
pub connection: deadpool_redis::Connection,
|
pub connection: deadpool_redis::Connection,
|
||||||
meta_namespace: String,
|
meta_namespace: Arc<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RedisPool {
|
impl RedisPool {
|
||||||
// initiate a new redis pool
|
// initiate a new redis pool
|
||||||
// testing pool uses a hashmap to mimic redis behaviour for very small data sizes (ie: tests)
|
// 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
|
// 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 =
|
let wait_timeout =
|
||||||
dotenvy::var("REDIS_WAIT_TIMEOUT_MS").ok().map_or_else(
|
dotenvy::var("REDIS_WAIT_TIMEOUT_MS").ok().map_or_else(
|
||||||
|| Duration::from_millis(15000),
|
|| Duration::from_millis(15000),
|
||||||
@@ -71,8 +72,8 @@ impl RedisPool {
|
|||||||
let pool = RedisPool {
|
let pool = RedisPool {
|
||||||
url,
|
url,
|
||||||
pool,
|
pool,
|
||||||
cache_list: DashMap::with_capacity(2048),
|
cache_list: Arc::new(DashMap::with_capacity(2048)),
|
||||||
meta_namespace: meta_namespace.unwrap_or("".to_string()),
|
meta_namespace: meta_namespace.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let redis_min_connections = dotenvy::var("REDIS_MIN_CONNECTIONS")
|
let redis_min_connections = dotenvy::var("REDIS_MIN_CONNECTIONS")
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ async fn app() -> std::io::Result<()> {
|
|||||||
.expect("Database connection failed");
|
.expect("Database connection failed");
|
||||||
|
|
||||||
// Redis connector
|
// Redis connector
|
||||||
let redis_pool = RedisPool::new(None);
|
let redis_pool = RedisPool::new("");
|
||||||
|
|
||||||
let storage_backend =
|
let storage_backend =
|
||||||
dotenvy::var("STORAGE_BACKEND").unwrap_or_else(|_| "local".to_string());
|
dotenvy::var("STORAGE_BACKEND").unwrap_or_else(|_| "local".to_string());
|
||||||
|
|||||||
@@ -497,7 +497,12 @@ async fn project_create_inner(
|
|||||||
{
|
{
|
||||||
let results = sqlx::query!(
|
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
|
create_data.slug
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ impl TemporaryDatabase {
|
|||||||
println!("Migrations complete");
|
println!("Migrations complete");
|
||||||
|
|
||||||
// Gets new Redis pool
|
// 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
|
// Create new meilisearch config
|
||||||
let search_config =
|
let search_config =
|
||||||
@@ -194,7 +194,7 @@ impl TemporaryDatabase {
|
|||||||
pool: pool.clone(),
|
pool: pool.clone(),
|
||||||
ro_pool: ReadOnlyPgPool::from(pool.clone()),
|
ro_pool: ReadOnlyPgPool::from(pool.clone()),
|
||||||
database_name: TEMPLATE_DATABASE_NAME.to_string(),
|
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)),
|
search_config: search::SearchConfig::new(Some(name)),
|
||||||
};
|
};
|
||||||
let setup_api =
|
let setup_api =
|
||||||
|
|||||||
Reference in New Issue
Block a user