refactor (backend-rs): misc/redis_cache -> database/cache

This commit is contained in:
naskya 2024-05-04 13:14:01 +09:00
parent f66ecd0759
commit 37e03007f0
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
4 changed files with 30 additions and 32 deletions

View file

@ -3,7 +3,7 @@ use redis::{Commands, RedisError};
use serde::{Deserialize, Serialize};
#[derive(thiserror::Error, Debug)]
pub enum CacheError {
pub enum Error {
#[error("Redis error: {0}")]
RedisError(#[from] RedisError),
#[error("Data serialization error: {0}")]
@ -16,11 +16,11 @@ fn prefix_key(key: &str) -> String {
redis_key(format!("cache:{}", key))
}
pub fn set_cache<V: for<'a> Deserialize<'a> + Serialize>(
pub fn set<V: for<'a> Deserialize<'a> + Serialize>(
key: &str,
value: &V,
expire_seconds: u64,
) -> Result<(), CacheError> {
) -> Result<(), Error> {
redis_conn()?.set_ex(
prefix_key(key),
rmp_serde::encode::to_vec(&value)?,
@ -29,9 +29,7 @@ pub fn set_cache<V: for<'a> Deserialize<'a> + Serialize>(
Ok(())
}
pub fn get_cache<V: for<'a> Deserialize<'a> + Serialize>(
key: &str,
) -> Result<Option<V>, CacheError> {
pub fn get<V: for<'a> Deserialize<'a> + Serialize>(key: &str) -> Result<Option<V>, Error> {
let serialized_value: Option<Vec<u8>> = redis_conn()?.get(prefix_key(key))?;
Ok(match serialized_value {
Some(v) => Some(rmp_serde::from_slice::<V>(v.as_ref())?),
@ -39,13 +37,13 @@ pub fn get_cache<V: for<'a> Deserialize<'a> + Serialize>(
})
}
pub fn delete_cache(key: &str) -> Result<(), CacheError> {
pub fn delete(key: &str) -> Result<(), Error> {
Ok(redis_conn()?.del(prefix_key(key))?)
}
#[cfg(test)]
mod unit_test {
use super::{get_cache, set_cache};
use super::{get, set};
use pretty_assertions::assert_eq;
#[test]
@ -68,13 +66,13 @@ mod unit_test {
kind: "prime number".to_string(),
};
set_cache(key_1, &value_1, 1).unwrap();
set_cache(key_2, &value_2, 1).unwrap();
set_cache(key_3, &value_3, 1).unwrap();
set(key_1, &value_1, 1).unwrap();
set(key_2, &value_2, 1).unwrap();
set(key_3, &value_3, 1).unwrap();
let cached_value_1: Vec<i32> = get_cache(key_1).unwrap().unwrap();
let cached_value_2: String = get_cache(key_2).unwrap().unwrap();
let cached_value_3: Data = get_cache(key_3).unwrap().unwrap();
let cached_value_1: Vec<i32> = get(key_1).unwrap().unwrap();
let cached_value_2: String = get(key_2).unwrap().unwrap();
let cached_value_3: Data = get(key_3).unwrap().unwrap();
assert_eq!(value_1, cached_value_1);
assert_eq!(value_2, cached_value_2);
@ -83,9 +81,9 @@ mod unit_test {
// wait for the cache to expire
std::thread::sleep(std::time::Duration::from_millis(1100));
let expired_value_1: Option<Vec<i32>> = get_cache(key_1).unwrap();
let expired_value_2: Option<Vec<i32>> = get_cache(key_2).unwrap();
let expired_value_3: Option<Vec<i32>> = get_cache(key_3).unwrap();
let expired_value_1: Option<Vec<i32>> = get(key_1).unwrap();
let expired_value_2: Option<Vec<i32>> = get(key_2).unwrap();
let expired_value_3: Option<Vec<i32>> = get(key_3).unwrap();
assert!(expired_value_1.is_none());
assert!(expired_value_2.is_none());

View file

@ -2,5 +2,6 @@ pub use postgresql::db_conn;
pub use redis::key as redis_key;
pub use redis::redis_conn;
pub mod cache;
pub mod postgresql;
pub mod redis;

View file

@ -1,4 +1,4 @@
use crate::misc::redis_cache::{get_cache, set_cache, CacheError};
use crate::database::cache;
use crate::util::http_client;
use image::{io::Reader, ImageError, ImageFormat};
use nom_exif::{parse_jpeg_exif, EntryValue, ExifTag};
@ -8,7 +8,7 @@ use tokio::sync::Mutex;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Redis cache error: {0}")]
CacheErr(#[from] CacheError),
CacheErr(#[from] cache::Error),
#[error("Reqwest error: {0}")]
ReqwestErr(#[from] reqwest::Error),
#[error("Image decoding error: {0}")]
@ -51,10 +51,10 @@ pub async fn get_image_size_from_url(url: &str) -> Result<ImageSize, Error> {
let _ = MTX_GUARD.lock().await;
let key = format!("fetchImage:{}", url);
attempted = get_cache::<bool>(&key)?.is_some();
attempted = cache::get::<bool>(&key)?.is_some();
if !attempted {
set_cache(&key, &true, 10 * 60)?;
cache::set(&key, &true, 10 * 60)?;
}
}
@ -109,7 +109,7 @@ pub async fn get_image_size_from_url(url: &str) -> Result<ImageSize, Error> {
#[cfg(test)]
mod unit_test {
use super::{get_image_size_from_url, ImageSize};
use crate::misc::redis_cache::delete_cache;
use crate::database::cache;
use pretty_assertions::assert_eq;
#[tokio::test]
@ -126,15 +126,15 @@ mod unit_test {
// Delete caches in case you run this test multiple times
// (should be disabled in CI tasks)
delete_cache(&format!("fetchImage:{}", png_url_1)).unwrap();
delete_cache(&format!("fetchImage:{}", png_url_2)).unwrap();
delete_cache(&format!("fetchImage:{}", png_url_3)).unwrap();
delete_cache(&format!("fetchImage:{}", rotated_jpeg_url)).unwrap();
delete_cache(&format!("fetchImage:{}", webp_url_1)).unwrap();
delete_cache(&format!("fetchImage:{}", webp_url_2)).unwrap();
delete_cache(&format!("fetchImage:{}", ico_url)).unwrap();
delete_cache(&format!("fetchImage:{}", gif_url)).unwrap();
delete_cache(&format!("fetchImage:{}", mp3_url)).unwrap();
cache::delete(&format!("fetchImage:{}", png_url_1)).unwrap();
cache::delete(&format!("fetchImage:{}", png_url_2)).unwrap();
cache::delete(&format!("fetchImage:{}", png_url_3)).unwrap();
cache::delete(&format!("fetchImage:{}", rotated_jpeg_url)).unwrap();
cache::delete(&format!("fetchImage:{}", webp_url_1)).unwrap();
cache::delete(&format!("fetchImage:{}", webp_url_2)).unwrap();
cache::delete(&format!("fetchImage:{}", ico_url)).unwrap();
cache::delete(&format!("fetchImage:{}", gif_url)).unwrap();
cache::delete(&format!("fetchImage:{}", mp3_url)).unwrap();
let png_size_1 = ImageSize {
width: 1024,

View file

@ -13,5 +13,4 @@ pub mod meta;
pub mod nyaify;
pub mod password;
pub mod reaction;
pub mod redis_cache;
pub mod remove_old_attestation_challenges;