Add redis caching to getting user notifications and projects [MOD-540] (#723)

* Add redis caching to getting a user's project ids

* Run `cargo sqlx prepare` to update the sqlx-data.json

* Add redis caching for getting user notifications

* Fix new clippy warnings

* Remove log that shouldn't have been committed

* Batch insert of notifications (untested)

* sqlx prepare...

* Fix merge conflict things and use new redis struct

* Fix bug with calling delete_many without any elements (caught by tests)

* cargo sqlx prepare

* Add tests around cache invalidation (and fix bug they caught!)

* Some test reorg based on code review suggestions
This commit is contained in:
Jackson Kruger
2023-10-12 17:52:24 -05:00
committed by GitHub
parent d66270eef0
commit abf4cd71ba
34 changed files with 848 additions and 379 deletions

View File

@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
const USERS_NAMESPACE: &str = "users";
const USER_USERNAMES_NAMESPACE: &str = "users_usernames";
// const USERS_PROJECTS_NAMESPACE: &str = "users_projects";
const USERS_PROJECTS_NAMESPACE: &str = "users_projects";
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct User {
@@ -234,12 +234,7 @@ impl User {
for user in db_users {
redis
.set(
USERS_NAMESPACE,
user.id.0,
serde_json::to_string(&user)?,
None,
)
.set_serialized_to_json(USERS_NAMESPACE, user.id.0, &user, None)
.await?;
redis
.set(
@@ -276,13 +271,22 @@ impl User {
pub async fn get_projects<'a, E>(
user_id: UserId,
exec: E,
) -> Result<Vec<ProjectId>, sqlx::Error>
redis: &RedisPool,
) -> Result<Vec<ProjectId>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
use futures::stream::TryStreamExt;
let projects = sqlx::query!(
let cached_projects = redis
.get_deserialized_from_json::<Vec<ProjectId>, _>(USERS_PROJECTS_NAMESPACE, user_id.0)
.await?;
if let Some(projects) = cached_projects {
return Ok(projects);
}
let db_projects = sqlx::query!(
"
SELECT m.id FROM mods m
INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.accepted = TRUE
@@ -296,7 +300,11 @@ impl User {
.try_collect::<Vec<ProjectId>>()
.await?;
Ok(projects)
redis
.set_serialized_to_json(USERS_PROJECTS_NAMESPACE, user_id.0, &db_projects, None)
.await?;
Ok(db_projects)
}
pub async fn get_collections<'a, E>(
@@ -365,6 +373,21 @@ impl User {
Ok(())
}
pub async fn clear_project_cache(
user_ids: &[UserId],
redis: &RedisPool,
) -> Result<(), DatabaseError> {
redis
.delete_many(
user_ids
.into_iter()
.map(|id| (USERS_PROJECTS_NAMESPACE, Some(id.0.to_string()))),
)
.await?;
Ok(())
}
pub async fn remove(
id: UserId,
full: bool,