Optimizations (#676)

This commit is contained in:
Geometrically 2023-08-07 23:05:08 -07:00 committed by GitHub
parent f21c756793
commit df83fcc5b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 278 additions and 244 deletions

1
.env
View File

@ -15,6 +15,7 @@ MEILISEARCH_ADDR=http://localhost:7700
MEILISEARCH_KEY=modrinth
REDIS_URL=redis://localhost
REDIS_MAX_CONNECTIONS=10000
BIND_ADDR=127.0.0.1:8000
SELF_ADDR=http://localhost:8000

View File

@ -0,0 +1,4 @@
CREATE INDEX threads_report_id
ON threads (report_id);
CREATE INDEX threads_mod_id
ON threads (mod_id);

View File

@ -1381,51 +1381,6 @@
},
"query": "\n UPDATE users\n SET password = $1\n WHERE (id = $2)\n "
},
"447350097928db863d47d756354cd52668f52f7156dd7f3673a826f7b9aca2fd": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int4"
},
{
"name": "version_",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "type_",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "created",
"ordinal": 3,
"type_info": "Timestamptz"
},
{
"name": "major",
"ordinal": 4,
"type_info": "Bool"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Bool",
"Text"
]
}
},
"query": "\n SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv\n WHERE major = $1 AND type = $2\n ORDER BY created DESC\n "
},
"4514723bdc1eb8a781215075bec51af1cc6fabe88a469338d5a59533eabf80c5": {
"describe": {
"columns": [
@ -2962,50 +2917,6 @@
},
"query": "\n DELETE FROM dependencies WHERE mod_dependency_id = $1\n "
},
"78a60cf0febcc6e35b8ffe38f2c021c13ab660c81c4775bbb26004d30242a1a8": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int4"
},
{
"name": "version_",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "type_",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "created",
"ordinal": 3,
"type_info": "Timestamptz"
},
{
"name": "major",
"ordinal": 4,
"type_info": "Bool"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Bool"
]
}
},
"query": "\n SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv\n WHERE major = $1\n ORDER BY created DESC\n "
},
"7916fe4f04067324ae05598ec9dc6f97f18baf9eda30c64f32677158ada87478": {
"describe": {
"columns": [],
@ -5616,50 +5527,6 @@
},
"query": "SELECT EXISTS(SELECT 1 FROM team_members WHERE id=$1)"
},
"e8ad94314ec2972c3102041b1bf06872c8e4c8a55156a17334a0e317fe41b784": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int4"
},
{
"name": "version_",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "type_",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "created",
"ordinal": 3,
"type_info": "Timestamptz"
},
{
"name": "major",
"ordinal": 4,
"type_info": "Bool"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "\n SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv\n WHERE type = $1\n ORDER BY created DESC\n "
},
"e8d4589132b094df1e7a3ca0440344fc8013c0d20b3c71a1142ccbee91fb3c70": {
"describe": {
"columns": [

View File

@ -3,7 +3,11 @@ use super::DatabaseError;
use chrono::DateTime;
use chrono::Utc;
use futures::TryStreamExt;
use serde::Deserialize;
use redis::cmd;
use serde::{Deserialize, Serialize};
const TAGS_NAMESPACE: &str = "tags";
const DEFAULT_EXPIRY: i64 = 1800; // 30 minutes
pub struct ProjectType {
pub id: ProjectTypeId,
@ -15,6 +19,7 @@ pub struct SideType {
pub name: String,
}
#[derive(Serialize, Deserialize)]
pub struct Loader {
pub id: LoaderId,
pub loader: String,
@ -22,7 +27,7 @@ pub struct Loader {
pub supported_project_types: Vec<String>,
}
#[derive(Clone, Deserialize, Debug)]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct GameVersion {
pub id: GameVersionId,
pub version: String,
@ -32,6 +37,7 @@ pub struct GameVersion {
pub major: bool,
}
#[derive(Serialize, Deserialize)]
pub struct Category {
pub id: CategoryId,
pub category: String,
@ -45,6 +51,7 @@ pub struct ReportType {
pub report_type: String,
}
#[derive(Serialize, Deserialize)]
pub struct DonationPlatform {
pub id: DonationPlatformId,
pub short: String,
@ -91,10 +98,24 @@ impl Category {
Ok(result.map(|r| CategoryId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<Category>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<Category>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:category", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<Category>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT c.id id, c.category category, c.icon icon, c.header category_header, pt.name project_type
@ -116,6 +137,14 @@ impl Category {
.try_collect::<Vec<Category>>()
.await?;
cmd("SET")
.arg(format!("{}:category", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}
@ -138,10 +167,24 @@ impl Loader {
Ok(result.map(|r| LoaderId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<Loader>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<Loader>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:loader", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<Loader>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT l.id id, l.loader loader, l.icon icon,
@ -169,6 +212,14 @@ impl Loader {
.try_collect::<Vec<_>>()
.await?;
cmd("SET")
.arg(format!("{}:loader", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}
@ -205,10 +256,24 @@ impl GameVersion {
Ok(result.map(|r| GameVersionId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<GameVersion>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<GameVersion>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:game_version", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<GameVersion>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major FROM game_versions gv
@ -226,6 +291,14 @@ impl GameVersion {
.try_collect::<Vec<GameVersion>>()
.await?;
cmd("SET")
.arg(format!("{}:game_version", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
@ -233,76 +306,28 @@ impl GameVersion {
version_type_option: Option<&str>,
major_option: Option<bool>,
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<GameVersion>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let result;
let result = Self::list(exec, redis)
.await?
.into_iter()
.filter(|x| {
let mut bool = true;
if let Some(version_type) = version_type_option {
bool &= &*x.type_ == version_type;
}
if let Some(major) = major_option {
result = sqlx::query!(
"
SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv
WHERE major = $1 AND type = $2
ORDER BY created DESC
",
major,
version_type
)
.fetch_many(exec)
.try_filter_map(|e| async { Ok(e.right().map(|c| GameVersion {
id: GameVersionId(c.id),
version: c.version_,
type_: c.type_,
created: c.created,
major: c.major,
})) })
.try_collect::<Vec<GameVersion>>()
.await?;
} else {
result = sqlx::query!(
"
SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv
WHERE type = $1
ORDER BY created DESC
",
version_type
)
.fetch_many(exec)
.try_filter_map(|e| async { Ok(e.right().map(|c| GameVersion {
id: GameVersionId(c.id),
version: c.version_,
type_: c.type_,
created: c.created,
major: c.major,
})) })
.try_collect::<Vec<GameVersion>>()
.await?;
}
} else if let Some(major) = major_option {
result = sqlx::query!(
"
SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major major FROM game_versions gv
WHERE major = $1
ORDER BY created DESC
",
major
)
.fetch_many(exec)
.try_filter_map(|e| async { Ok(e.right().map(|c| GameVersion {
id: GameVersionId(c.id),
version: c.version_,
type_: c.type_,
created: c.created,
major: c.major,
})) })
.try_collect::<Vec<GameVersion>>()
.await?;
} else {
result = Vec::new();
bool &= x.major == major;
}
bool
})
.collect();
Ok(result)
}
}
@ -381,10 +406,24 @@ impl DonationPlatform {
Ok(result.map(|r| DonationPlatformId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<DonationPlatform>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<DonationPlatform>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:donation_platform", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<DonationPlatform>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT id, short, name FROM donation_platforms
@ -401,6 +440,14 @@ impl DonationPlatform {
.try_collect::<Vec<DonationPlatform>>()
.await?;
cmd("SET")
.arg(format!("{}:donation_platform", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}
@ -423,10 +470,24 @@ impl ReportType {
Ok(result.map(|r| ReportTypeId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<String>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<String>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:report_type", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<String>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT name FROM report_types
@ -437,6 +498,14 @@ impl ReportType {
.try_collect::<Vec<String>>()
.await?;
cmd("SET")
.arg(format!("{}:report_type", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}
@ -459,10 +528,24 @@ impl ProjectType {
Ok(result.map(|r| ProjectTypeId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<String>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<String>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:project_type", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<String>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT name FROM project_types
@ -473,6 +556,14 @@ impl ProjectType {
.try_collect::<Vec<String>>()
.await?;
cmd("SET")
.arg(format!("{}:project_type", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}
@ -495,10 +586,24 @@ impl SideType {
Ok(result.map(|r| SideTypeId(r.id)))
}
pub async fn list<'a, E>(exec: E) -> Result<Vec<String>, DatabaseError>
pub async fn list<'a, E>(
exec: E,
redis: &deadpool_redis::Pool,
) -> Result<Vec<String>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let mut redis = redis.get().await?;
let res = cmd("GET")
.arg(format!("{}:side_type", TAGS_NAMESPACE))
.query_async::<_, Option<String>>(&mut redis)
.await?
.and_then(|x| serde_json::from_str::<Vec<String>>(&x).ok());
if let Some(res) = res {
return Ok(res);
}
let result = sqlx::query!(
"
SELECT name FROM side_types
@ -509,6 +614,14 @@ impl SideType {
.try_collect::<Vec<String>>()
.await?;
cmd("SET")
.arg(format!("{}:side_type", TAGS_NAMESPACE))
.arg(serde_json::to_string(&result)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)
.query_async::<_, ()>(&mut redis)
.await?;
Ok(result)
}
}

View File

@ -161,13 +161,13 @@ pub struct DonationPlatformId(pub i32);
#[derive(Copy, Clone, Debug, Type, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[sqlx(transparent)]
pub struct VersionId(pub i64);
#[derive(Copy, Clone, Debug, Type, Deserialize)]
#[derive(Copy, Clone, Debug, Type, Deserialize, Serialize)]
#[sqlx(transparent)]
pub struct GameVersionId(pub i32);
#[derive(Copy, Clone, Debug, Type)]
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize)]
#[sqlx(transparent)]
pub struct LoaderId(pub i32);
#[derive(Copy, Clone, Debug, Type)]
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize)]
#[sqlx(transparent)]
pub struct CategoryId(pub i32);

View File

@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
const PROJECTS_NAMESPACE: &str = "projects";
const PROJECTS_SLUGS_NAMESPACE: &str = "projects_slugs";
const PROJECTS_DEPENDENCIES_NAMESPACE: &str = "projects_dependencies";
const DEFAULT_EXPIRY: i64 = 3600; // 60 minutes
const DEFAULT_EXPIRY: i64 = 1800; // 30 minutes
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DonationUrl {
@ -524,7 +524,8 @@ impl Project {
{
remaining_strings.retain(|x| {
&to_base62(project.inner.id.0 as u64) != x
&& project.inner.slug.as_ref() != Some(x)
&& project.inner.slug.as_ref().map(|x| x.to_lowercase())
!= Some(x.to_lowercase())
});
found_projects.push(project);
continue;

View File

@ -185,8 +185,10 @@ impl User {
for user in users {
if let Some(user) = user.and_then(|x| serde_json::from_str::<User>(&x).ok()) {
remaining_strings
.retain(|x| &to_base62(user.id.0 as u64) != x && &user.username != x);
remaining_strings.retain(|x| {
&to_base62(user.id.0 as u64) != x
&& user.username.to_lowercase() != x.to_lowercase()
});
found_users.push(user);
continue;
}

View File

@ -716,7 +716,7 @@ impl Version {
for (key, mut files) in save_files {
cmd("SET")
.arg(format!("{}:{}", VERSIONS_NAMESPACE, key))
.arg(format!("{}:{}", VERSION_FILES_NAMESPACE, key))
.arg(serde_json::to_string(&files)?)
.arg("EX")
.arg(DEFAULT_EXPIRY)

View File

@ -79,9 +79,17 @@ async fn main() -> std::io::Result<()> {
.expect("Database connection failed");
// Redis connector
let redis_cfg = Config::from_url(dotenvy::var("REDIS_URL").expect("Redis URL not set"));
let redis_pool = redis_cfg
.create_pool(Some(Runtime::Tokio1))
let redis_pool = Config::from_url(dotenvy::var("REDIS_URL").expect("Redis URL not set"))
.builder()
.expect("Error building Redis pool")
.max_size(
dotenvy::var("DATABASE_MAX_CONNECTIONS")
.ok()
.and_then(|x| x.parse().ok())
.unwrap_or(10000),
)
.runtime(Runtime::Tokio1)
.build()
.expect("Redis connection failed");
let storage_backend = dotenvy::var("STORAGE_BACKEND").unwrap_or_else(|_| "local".to_string());
@ -175,6 +183,7 @@ async fn main() -> std::io::Result<()> {
// Reminding moderators to review projects which have been in the queue longer than 40hr
let pool_ref = pool.clone();
let redis_ref = redis_pool.clone();
let webhook_message_sent = Arc::new(Mutex::new(Vec::<(
database::models::ProjectId,
DateTime<Utc>,
@ -182,6 +191,7 @@ async fn main() -> std::io::Result<()> {
scheduler.run(std::time::Duration::from_secs(10 * 60), move || {
let pool_ref = pool_ref.clone();
let redis_ref = redis_ref.clone();
let webhook_message_sent_ref = webhook_message_sent.clone();
info!("Checking reviewed projects submitted more than 40hrs ago");
@ -217,6 +227,7 @@ async fn main() -> std::io::Result<()> {
util::webhook::send_discord_webhook(
project.into(),
&pool_ref,
&redis_ref,
webhook_url,
Some("<@&783155186491195394> This project has been in the queue for over 40 hours!".to_string()),
)

View File

@ -367,8 +367,8 @@ async fn project_create_inner(
let mut versions_map = std::collections::HashMap::new();
let mut gallery_urls = Vec::new();
let all_game_versions = models::categories::GameVersion::list(&mut *transaction).await?;
let all_loaders = models::categories::Loader::list(&mut *transaction).await?;
let all_game_versions = models::categories::GameVersion::list(&mut *transaction, redis).await?;
let all_loaders = models::categories::Loader::list(&mut *transaction, redis).await?;
{
// The first multipart field must be named "data" and contain a
@ -836,7 +836,13 @@ async fn project_create_inner(
if status == ProjectStatus::Processing {
if let Ok(webhook_url) = dotenvy::var("MODERATION_DISCORD_WEBHOOK") {
crate::util::webhook::send_discord_webhook(response.id, pool, webhook_url, None)
crate::util::webhook::send_discord_webhook(
response.id,
pool,
redis,
webhook_url,
None,
)
.await
.ok();
}

View File

@ -504,6 +504,7 @@ pub async fn project_edit(
crate::util::webhook::send_discord_webhook(
project_item.inner.id.into(),
&pool,
&redis,
webhook_url,
None,
)
@ -530,6 +531,7 @@ pub async fn project_edit(
crate::util::webhook::send_discord_webhook(
project_item.inner.id.into(),
&pool,
&redis,
webhook_url,
None,
)
@ -1251,8 +1253,9 @@ pub async fn projects_edit(
let team_members =
database::models::TeamMember::get_from_team_full_many(&team_ids, &**pool, &redis).await?;
let categories = database::models::categories::Category::list(&**pool).await?;
let donation_platforms = database::models::categories::DonationPlatform::list(&**pool).await?;
let categories = database::models::categories::Category::list(&**pool, &redis).await?;
let donation_platforms =
database::models::categories::DonationPlatform::list(&**pool, &redis).await?;
let mut transaction = pool.begin().await?;

View File

@ -30,8 +30,11 @@ pub struct CategoryData {
}
#[get("category")]
pub async fn category_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let results = Category::list(&**pool)
pub async fn category_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results = Category::list(&**pool, &redis)
.await?
.into_iter()
.map(|x| CategoryData {
@ -53,8 +56,11 @@ pub struct LoaderData {
}
#[get("loader")]
pub async fn loader_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let mut results = Loader::list(&**pool)
pub async fn loader_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let mut results = Loader::list(&**pool, &redis)
.await?
.into_iter()
.map(|x| LoaderData {
@ -88,11 +94,12 @@ pub struct GameVersionQuery {
pub async fn game_version_list(
pool: web::Data<PgPool>,
query: web::Query<GameVersionQuery>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results: Vec<GameVersionQueryData> = if query.type_.is_some() || query.major.is_some() {
GameVersion::list_filter(query.type_.as_deref(), query.major, &**pool).await?
GameVersion::list_filter(query.type_.as_deref(), query.major, &**pool, &redis).await?
} else {
GameVersion::list(&**pool).await?
GameVersion::list(&**pool, &redis).await?
}
.into_iter()
.map(|x| GameVersionQueryData {
@ -163,8 +170,11 @@ pub struct DonationPlatformQueryData {
}
#[get("donation_platform")]
pub async fn donation_platform_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let results: Vec<DonationPlatformQueryData> = DonationPlatform::list(&**pool)
pub async fn donation_platform_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results: Vec<DonationPlatformQueryData> = DonationPlatform::list(&**pool, &redis)
.await?
.into_iter()
.map(|x| DonationPlatformQueryData {
@ -176,19 +186,28 @@ pub async fn donation_platform_list(pool: web::Data<PgPool>) -> Result<HttpRespo
}
#[get("report_type")]
pub async fn report_type_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let results = ReportType::list(&**pool).await?;
pub async fn report_type_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results = ReportType::list(&**pool, &redis).await?;
Ok(HttpResponse::Ok().json(results))
}
#[get("project_type")]
pub async fn project_type_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let results = ProjectType::list(&**pool).await?;
pub async fn project_type_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results = ProjectType::list(&**pool, &redis).await?;
Ok(HttpResponse::Ok().json(results))
}
#[get("side_type")]
pub async fn side_type_list(pool: web::Data<PgPool>) -> Result<HttpResponse, ApiError> {
let results = SideType::list(&**pool).await?;
pub async fn side_type_list(
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
) -> Result<HttpResponse, ApiError> {
let results = SideType::list(&**pool, &redis).await?;
Ok(HttpResponse::Ok().json(results))
}

View File

@ -135,8 +135,8 @@ async fn version_create_inner(
let mut initial_version_data = None;
let mut version_builder = None;
let all_game_versions = models::categories::GameVersion::list(&mut *transaction).await?;
let all_loaders = models::categories::Loader::list(&mut *transaction).await?;
let all_game_versions = models::categories::GameVersion::list(&mut *transaction, redis).await?;
let all_loaders = models::categories::Loader::list(&mut *transaction, redis).await?;
let user = get_user_from_headers(
&req,
@ -561,7 +561,8 @@ async fn upload_file_to_version_inner(
.await?
.name;
let all_game_versions = models::categories::GameVersion::list(&mut *transaction).await?;
let all_game_versions =
models::categories::GameVersion::list(&mut *transaction, &redis).await?;
let mut error = None;
while let Some(item) = payload.next().await {

View File

@ -115,8 +115,13 @@ pub async fn version_list(
// Attempt to populate versions with "auto featured" versions
if response.is_empty() && !versions.is_empty() && filters.featured.unwrap_or(false) {
let (loaders, game_versions) = futures::future::try_join(
database::models::categories::Loader::list(&**pool),
database::models::categories::GameVersion::list_filter(None, Some(true), &**pool),
database::models::categories::Loader::list(&**pool, &redis),
database::models::categories::GameVersion::list_filter(
None,
Some(true),
&**pool,
&redis,
),
)
.await?;

View File

@ -72,10 +72,11 @@ const PLUGIN_LOADERS: &[&str] = &[
pub async fn send_discord_webhook(
project_id: ProjectId,
pool: &PgPool,
redis: &deadpool_redis::Pool,
webhook_url: String,
message: Option<String>,
) -> Result<(), ApiError> {
let all_game_versions = GameVersion::list(pool).await?;
let all_game_versions = GameVersion::list(pool, redis).await?;
let row =
sqlx::query!(