caching implementation

This commit is contained in:
2025-10-20 00:53:27 +01:00
parent 561999f4f1
commit f6d2999b96
16 changed files with 372 additions and 64 deletions
+52 -12
View File
@@ -2,6 +2,7 @@
#[macro_use]
extern crate rocket;
use redis::cmd;
use rocket::fs::{FileServer, NamedFile};
use rocket::http::Method;
use rocket::serde::json::Json;
@@ -13,7 +14,6 @@ use std::sync::Arc;
use crate::auth::Session;
use crate::db::{Postgres, Redis};
use crate::messages::ChatBroadcaster;
pub mod auth;
pub mod cdn;
@@ -35,20 +35,18 @@ async fn users(_ag: Session, mut db: Connection<Postgres>) -> Json<Vec<i32>> {
}
#[get("/users/<id>", rank = 1)]
async fn display_name(id: usize, _ag: Session, mut db: Connection<Postgres>) -> String {
sqlx::query!(
"SELECT display_name, username FROM users WHERE id = $1",
id as i32
)
.fetch_one(&mut **db)
.await
.map(|row| row.display_name.unwrap_or(row.username))
.unwrap_or_else(|_| "User not found".to_string())
async fn display_name(
id: usize,
_ag: Session,
mut pgsql_conn: Connection<Postgres>,
mut redis_conn: Connection<Redis>,
) -> String {
UserCache::username(id, &mut redis_conn, &mut pgsql_conn).await
}
#[launch]
fn rocket() -> Rocket<Build> {
let chat = Arc::new(ChatBroadcaster::new(32));
let chat = Arc::new(crate::messages::ChatBroadcaster::new(32));
let cors = CorsOptions::default()
.allowed_origins(AllowedOrigins::all())
@@ -73,7 +71,6 @@ fn rocket() -> Rocket<Build> {
routes![
favicon,
messages::chat_page,
messages::chat_page_preview,
auth::signup_page,
auth::login_page,
auth::mfa_page,
@@ -83,6 +80,7 @@ fn rocket() -> Rocket<Build> {
.mount(
"/api",
routes![
cdn::upload_profile_pic,
messages::get_messages,
messages::post_message,
messages::event_stream,
@@ -109,3 +107,45 @@ fn rocket() -> Rocket<Build> {
async fn favicon() -> NamedFile {
NamedFile::open("static/favicon.ico").await.unwrap()
}
pub struct UserCache {}
impl UserCache {
pub async fn username(
id: usize,
redis_conn: &mut Connection<Redis>,
pgsql_conn: &mut Connection<Postgres>,
) -> String {
if let Ok(val) = cmd("GET")
.arg(&[format!("users:{id}")])
.query_async(&mut **redis_conn)
.await
{
return val;
}
if let Ok(v) = sqlx::query!("SELECT username FROM users WHERE id = $1", id as i32)
.fetch_one(&mut ***pgsql_conn)
.await
{
let username = v.username;
Self::insert(id, &username, redis_conn).await;
username
} else {
unimplemented!()
}
}
pub async fn insert(id: usize, username: &str, conn: &mut Connection<Redis>) {
cmd("SET")
.arg(&[
format!("users:{id}"),
username.to_string(),
"EX".to_string(),
"1800".to_string(),
])
.query_async(&mut **conn)
.await
.expect("failed to insert key")
}
}