diff --git a/backend/public/Cargo.lock b/backend/public/Cargo.lock index a313c98..51f31a9 100644 --- a/backend/public/Cargo.lock +++ b/backend/public/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -59,6 +59,12 @@ dependencies = [ "libc", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "async-trait" version = "0.1.82" @@ -209,6 +215,16 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + [[package]] name = "cc" version = "1.1.21" @@ -253,6 +269,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "cookie-factory" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -283,6 +305,12 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" + [[package]] name = "crossbeam-queue" version = "0.3.11" @@ -403,6 +431,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "float-cmp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" +dependencies = [ + "num-traits", +] + [[package]] name = "flume" version = "0.11.0" @@ -439,6 +476,43 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fred" +version = "10.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a7b2fd0f08b23315c13b6156f971aeedb6f75fb16a29ac1872d2eabccc1490e" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "bytes-utils", + "float-cmp", + "fred-macros", + "futures", + "log", + "parking_lot", + "rand", + "redis-protocol", + "semver", + "socket2", + "tokio", + "tokio-stream", + "tokio-util", + "url", + "urlencoding", +] + +[[package]] +name = "fred-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1458c6e22d36d61507034d5afecc64f105c1d39712b7ac6ec3b352c423f715cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures" version = "0.3.30" @@ -1180,6 +1254,7 @@ dependencies = [ "axum", "chrono", "dotenvy", + "fred", "serde", "serde_json", "sqlx", @@ -1254,6 +1329,20 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redis-protocol" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdba59219406899220fc4cdfd17a95191ba9c9afb719b5fa5a083d63109a9f1" +dependencies = [ + "bytes", + "bytes-utils", + "cookie-factory", + "crc16", + "log", + "nom", +] + [[package]] name = "redox_syscall" version = "0.5.4" @@ -1420,6 +1509,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" version = "1.0.210" @@ -2142,6 +2237,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "valuable" version = "0.1.0" diff --git a/backend/public/Cargo.toml b/backend/public/Cargo.toml index f4f7b7c..b626412 100644 --- a/backend/public/Cargo.toml +++ b/backend/public/Cargo.toml @@ -24,3 +24,4 @@ serde = "1.0.210" serde_json = "1.0.128" chrono = "0.4.38" xml = "0.8.20" +fred = "10.1.0" diff --git a/backend/public/src/main.rs b/backend/public/src/main.rs index 9f62690..c516d01 100644 --- a/backend/public/src/main.rs +++ b/backend/public/src/main.rs @@ -16,12 +16,9 @@ use tracing_subscriber::{filter, layer::SubscriberExt, prelude::*, util::Subscri mod config; mod datasources; mod routes; +mod state; mod utils; -pub struct AppState { - db: PgPool, -} - #[tokio::main] async fn main() { // setting up configuration diff --git a/backend/public/src/state.rs b/backend/public/src/state.rs new file mode 100644 index 0000000..ab662a9 --- /dev/null +++ b/backend/public/src/state.rs @@ -0,0 +1,73 @@ +use fred::interfaces::KeysInterface; +use fred::{clients::Pool, prelude::*}; +use serde_json::Value; +use sqlx::PgPool; + +pub type AppState = std::sync::Arc>; + +pub struct AppInternalState { + pub database: sqlx::postgres::PgPool, + pub cache: Cache, +} + +pub struct Cache { + pub inmem: Pool, +} + +impl AppInternalState { + pub fn new(database: PgPool, cache: Pool) -> Self { + AppInternalState { + database, + cache: Cache { inmem: cache }, + } + } +} + +impl Cache { + pub async fn get(&mut self, key: String) -> Result, Box> + where + T: for<'de> serde::Deserialize<'de>, + { + if !self.inmem.is_connected() { + return Err(Box::new("Are you connected to the cache?".into())); + } + + let value: Option = self.inmem.get(key).await?; + + let result = match value { + Some(x) => match serde_json::from_value(x) { + Ok(x) => Some(x), + Err(_) => None, + }, + None => None, + }; + Ok(result) + } + + pub async fn set( + &mut self, + key: String, + contents: &T, + expiration: Option, + set_opts: Option, + get: bool, + ) -> Result<(), Box> + where + T: for<'de> serde::Deserialize<'de>, + { + if !self.inmem.is_connected() { + return Err(Box::new("Are you connected to the cache?".into())); + } + + let value: Value = serde_json::to_value(contents)?; + self.inmem + .set(key, value.to_string(), expiration, set_opts, get) + .await?; + Ok(()) + } + + pub async fn del(&mut self, key: String) -> Result<(), Box> { + self.inmem.del(key).await?; + Ok(()) + } +}