mirror of
https://git.joinfirefish.org/firefish/firefish.git
synced 2024-05-19 07:51:11 +02:00
dev (backend-rs): add basic Redis cache setter/getter
This commit is contained in:
parent
9acd130a22
commit
08926ceb8c
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -222,6 +222,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"redis",
|
"redis",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rmp-serde",
|
||||||
"schemars",
|
"schemars",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2012,6 +2013,28 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp"
|
||||||
|
version = "0.8.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"num-traits",
|
||||||
|
"paste",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp-serde"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938a142ab806f18b88a97b0dea523d39e0fd730a064b035726adcfc58a8a5188"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"rmp",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
|
|
|
@ -28,6 +28,7 @@ quote = "1.0.36"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
redis = "0.25.3"
|
redis = "0.25.3"
|
||||||
regex = "1.10.4"
|
regex = "1.10.4"
|
||||||
|
rmp-serde = "1.2.0"
|
||||||
schemars = "0.8.16"
|
schemars = "0.8.16"
|
||||||
sea-orm = "0.12.15"
|
sea-orm = "0.12.15"
|
||||||
serde = "1.0.197"
|
serde = "1.0.197"
|
||||||
|
|
|
@ -32,6 +32,7 @@ parse-display = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
redis = { workspace = true }
|
redis = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
|
rmp-serde = { workspace = true }
|
||||||
schemars = { workspace = true, features = ["chrono"] }
|
schemars = { workspace = true, features = ["chrono"] }
|
||||||
sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls"] }
|
sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls"] }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|
|
@ -11,3 +11,4 @@ pub mod meta;
|
||||||
pub mod nyaify;
|
pub mod nyaify;
|
||||||
pub mod password;
|
pub mod password;
|
||||||
pub mod reaction;
|
pub mod reaction;
|
||||||
|
pub mod redis_cache;
|
||||||
|
|
84
packages/backend-rs/src/misc/redis_cache.rs
Normal file
84
packages/backend-rs/src/misc/redis_cache.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
use crate::database::{redis_conn, redis_key};
|
||||||
|
use redis::{Commands, RedisError};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Redis error: {0}")]
|
||||||
|
RedisError(#[from] RedisError),
|
||||||
|
#[error("Data serialization error: {0}")]
|
||||||
|
SerializeError(#[from] rmp_serde::encode::Error),
|
||||||
|
#[error("Data deserialization error: {0}")]
|
||||||
|
DeserializeError(#[from] rmp_serde::decode::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_cache<V: for<'a> Deserialize<'a> + Serialize>(
|
||||||
|
key: &str,
|
||||||
|
value: &V,
|
||||||
|
expire_seconds: u64,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
redis_conn()?.set_ex(
|
||||||
|
redis_key(key),
|
||||||
|
rmp_serde::encode::to_vec(&value)?,
|
||||||
|
expire_seconds,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cache<V: for<'a> Deserialize<'a> + Serialize>(key: &str) -> Result<Option<V>, Error> {
|
||||||
|
let serialized_value: Option<Vec<u8>> = redis_conn()?.get(redis_key(key))?;
|
||||||
|
Ok(match serialized_value {
|
||||||
|
Some(v) => Some(rmp_serde::from_slice::<V>(v.as_ref())?),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod unit_test {
|
||||||
|
use super::{get_cache, set_cache};
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_get_expire() {
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Debug)]
|
||||||
|
struct Data {
|
||||||
|
id: u32,
|
||||||
|
kind: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let key_1 = "CARGO_TEST_CACHE_KEY_1";
|
||||||
|
let value_1: Vec<i32> = vec![1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
let key_2 = "CARGO_TEST_CACHE_KEY_2";
|
||||||
|
let value_2 = "Hello fedizens".to_string();
|
||||||
|
|
||||||
|
let key_3 = "CARGO_TEST_CACHE_KEY_3";
|
||||||
|
let value_3 = Data {
|
||||||
|
id: 1000000007,
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
assert_eq!(value_1, cached_value_1);
|
||||||
|
assert_eq!(value_2, cached_value_2);
|
||||||
|
assert_eq!(value_3, cached_value_3);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
assert!(expired_value_1.is_none());
|
||||||
|
assert!(expired_value_2.is_none());
|
||||||
|
assert!(expired_value_3.is_none());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue