From 8116307ba07b88e7ee481de39ac0dfa9decf3b21 Mon Sep 17 00:00:00 2001 From: trisua Date: Sun, 17 Aug 2025 14:52:29 -0400 Subject: [PATCH] add: app data query cache option --- Cargo.lock | 65 ++++++++++--------- crates/app/Cargo.toml | 4 +- crates/app/src/public/html/developer/app.lisp | 6 +- crates/app/src/routes/api/v1/app_data.rs | 53 ++++++++++++--- crates/app/src/routes/api/v1/mod.rs | 1 + crates/core/Cargo.toml | 10 +-- crates/core/examples/sdk_db.rs | 2 + crates/core/src/model/apps.rs | 3 + crates/core/src/sdk.rs | 1 + crates/l10n/Cargo.toml | 2 +- crates/shared/Cargo.toml | 2 +- 11 files changed, 100 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56b0651..9bfe6cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,9 +354,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" [[package]] name = "bitstream-io" @@ -725,9 +725,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "emojis" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf035af17e73b37a9ac6b0efda5f1f4974ee6f6080e33dda268086e84fbcbd1" +checksum = "f52f3d011046a013bdefbc63a5523b06ad0c0f1e227941baf98475496229d634" dependencies = [ "phf 0.12.1", ] @@ -1062,7 +1062,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "ignore", "walkdir", ] @@ -1372,7 +1372,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -1608,7 +1608,7 @@ version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cfg-if", "libc", ] @@ -2043,7 +2043,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cfg-if", "foreign-types", "libc", @@ -2384,7 +2384,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "getopts", "memchr", "pulldown-cmark-escape", @@ -2642,7 +2642,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -2691,9 +2691,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes", @@ -2765,7 +2765,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "errno", "libc", "linux-raw-sys", @@ -2875,7 +2875,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -2888,7 +2888,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -3065,9 +3065,12 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "slug" @@ -3236,7 +3239,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3350,12 +3353,12 @@ dependencies = [ [[package]] name = "tetratto-core" -version = "15.0.0" +version = "15.0.1" dependencies = [ "async-recursion", "base16ct", "base64 0.22.1", - "bitflags 2.9.1", + "bitflags 2.9.2", "emojis", "md-5", "oiseau", @@ -3368,7 +3371,7 @@ dependencies = [ "tetratto-l10n", "tetratto-shared", "tokio", - "toml 0.9.4", + "toml 0.9.5", "totp-rs", ] @@ -3378,7 +3381,7 @@ version = "12.0.0" dependencies = [ "pathbufd", "serde", - "toml 0.9.4", + "toml 0.9.5", ] [[package]] @@ -3394,7 +3397,7 @@ dependencies = [ "serde", "sha2", "snowflaked", - "uuid 1.17.0", + "uuid 1.18.0", ] [[package]] @@ -3628,9 +3631,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1" +checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ "indexmap", "serde", @@ -3674,9 +3677,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" dependencies = [ "winnow", ] @@ -3726,7 +3729,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "bytes", "futures-core", "futures-util", @@ -3993,9 +3996,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -4560,7 +4563,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index bbbe59c..f817b9c 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -27,7 +27,7 @@ tetratto-shared = { path = "../shared" } tetratto-core = { path = "../core" } tetratto-l10n = { path = "../l10n" } image = "0.25.6" -reqwest = { version = "0.12.22", features = ["json", "stream"] } +reqwest = { version = "0.12.23", features = ["json", "stream"] } regex = "1.11.1" serde_json = "1.0.142" mime_guess = "2.0.5" @@ -42,7 +42,7 @@ async-stripe = { version = "0.41.0", features = [ "runtime-tokio-hyper", "connect", ] } -emojis = "0.7.1" +emojis = "0.7.2" webp = "0.3.0" nanoneo = "0.2.0" cookie = "0.18.1" diff --git a/crates/app/src/public/html/developer/app.lisp b/crates/app/src/public/html/developer/app.lisp index 86c43e4..35a3709 100644 --- a/crates/app/src/public/html/developer/app.lisp +++ b/crates/app/src/public/html/developer/app.lisp @@ -65,7 +65,11 @@ (option ("value" "Tier3") ("selected" "{% if app.storage_capacity == 'Tier3' -%}true{% else %}false{%- endif %}") - (text "Tier 3 (100 MB)"))))) + (text "Tier 3 (100 MB)")) + (option + ("value" "Unlimited") + ("selected" "{% if app.storage_capacity == 'Unlimited' -%}true{% else %}false{%- endif %}") + (text "Unlimited"))))) (text "{%- endif %}") (div ("class" "card_nest") diff --git a/crates/app/src/routes/api/v1/app_data.rs b/crates/app/src/routes/api/v1/app_data.rs index b5fa212..7c2de89 100644 --- a/crates/app/src/routes/api/v1/app_data.rs +++ b/crates/app/src/routes/api/v1/app_data.rs @@ -4,10 +4,14 @@ use crate::{ State, }; use axum::{extract::Path, http::HeaderMap, response::IntoResponse, Extension, Json}; -use tetratto_core::model::{ - apps::{AppData, AppDataQuery, AppDataQueryResult}, - ApiReturn, Error, +use tetratto_core::{ + cache::Cache, + model::{ + apps::{AppData, AppDataQuery, AppDataQueryResult}, + ApiReturn, Error, + }, }; +use tetratto_shared::hash::hash; pub async fn get_app_request( headers: HeaderMap, @@ -37,6 +41,24 @@ pub async fn query_request( None => return Json(Error::NotAllowed.into()), }; + let query_hash = hash(serde_json::to_string(&req.query).unwrap()); + let redis_query_key = format!("atto.app.{}:{query_hash}", app.id); + + if req.cache { + if let Some(x) = data.0.1.get(redis_query_key.clone()).await { + match serde_json::from_str::(&x) { + Ok(x) => { + return Json(ApiReturn { + ok: true, + message: "Success".to_string(), + payload: Some(x), + }); + } + Err(e) => return Json(Error::MiscError(e.to_string()).into()), + } + } + } + match data .query_app_data(AppDataQuery { app: app.id, @@ -45,11 +67,26 @@ pub async fn query_request( }) .await { - Ok(x) => Json(ApiReturn { - ok: true, - message: "Success".to_string(), - payload: Some(x), - }), + Ok(x) => { + // store + if req.cache { + if !data + .0 + .1 + .set(redis_query_key, serde_json::to_string(&x).unwrap()) + .await + { + return Json(Error::Unknown.into()); + } + } + + // ... + Json(ApiReturn { + ok: true, + message: "Success".to_string(), + payload: Some(x), + }) + } Err(e) => Json(e.into()), } } diff --git a/crates/app/src/routes/api/v1/mod.rs b/crates/app/src/routes/api/v1/mod.rs index 4b33b93..1f7632a 100644 --- a/crates/app/src/routes/api/v1/mod.rs +++ b/crates/app/src/routes/api/v1/mod.rs @@ -1276,6 +1276,7 @@ pub struct InsertAppData { pub struct QueryAppData { pub query: AppDataSelectQuery, pub mode: AppDataSelectMode, + pub cache: bool, } #[derive(Deserialize)] diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 1904994..1a0cd88 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tetratto-core" description = "The core behind Tetratto" -version = "15.0.0" +version = "15.0.1" edition = "2024" authors.workspace = true repository.workspace = true @@ -23,7 +23,7 @@ default = ["database", "types", "sdk"] [dependencies] pathbufd = "0.1.4" serde = { version = "1.0.219", features = ["derive"] } -toml = "0.9.4" +toml = "0.9.5" tetratto-shared = { version = "12.0.6", path = "../shared" } tetratto-l10n = { version = "12.0.0", path = "../l10n" } serde_json = "1.0.142" @@ -31,16 +31,16 @@ totp-rs = { version = "5.7.0", features = [ "qr", "gen_secret", ], optional = true } -reqwest = { version = "0.12.22", features = [ +reqwest = { version = "0.12.23", features = [ "json", "multipart", ], optional = true } -bitflags = { version = "2.9.1", optional = true } +bitflags = { version = "2.9.2", optional = true } async-recursion = { version = "1.1.1", optional = true } md-5 = { version = "0.10.6", optional = true } base16ct = { version = "0.2.0", features = ["alloc"], optional = true } base64 = { version = "0.22.1", optional = true } -emojis = "0.7.1" +emojis = "0.7.2" regex = "1.11.1" oiseau = { version = "0.1.2", default-features = false, features = [ "postgres", diff --git a/crates/core/examples/sdk_db.rs b/crates/core/examples/sdk_db.rs index becdca1..0607824 100644 --- a/crates/core/examples/sdk_db.rs +++ b/crates/core/examples/sdk_db.rs @@ -28,6 +28,7 @@ pub async fn main() { .query(&SimplifiedQuery { query: AppDataSelectQuery::KeyIs("rust_test".to_string()), mode: AppDataSelectMode::One(0), + cache: false, }) .await .unwrap() @@ -49,6 +50,7 @@ pub async fn main() { .query(&SimplifiedQuery { query: AppDataSelectQuery::KeyIs("rust_test".to_string()), mode: AppDataSelectMode::One(0), + cache: false, }) .await .unwrap() diff --git a/crates/core/src/model/apps.rs b/crates/core/src/model/apps.rs index 470bc8b..5aba87a 100644 --- a/crates/core/src/model/apps.rs +++ b/crates/core/src/model/apps.rs @@ -32,6 +32,8 @@ pub enum DeveloperPassStorageQuota { Tier2, /// The app is limited to 100 MB. Tier3, + /// The app is not limited. + Unlimited, } impl Default for DeveloperPassStorageQuota { @@ -46,6 +48,7 @@ impl DeveloperPassStorageQuota { DeveloperPassStorageQuota::Tier1 => 26214400, DeveloperPassStorageQuota::Tier2 => 52428800, DeveloperPassStorageQuota::Tier3 => 104857600, + DeveloperPassStorageQuota::Unlimited => usize::MAX, } } } diff --git a/crates/core/src/sdk.rs b/crates/core/src/sdk.rs index 0e5add6..b7f00bd 100644 --- a/crates/core/src/sdk.rs +++ b/crates/core/src/sdk.rs @@ -31,6 +31,7 @@ macro_rules! api_return_ok { pub struct SimplifiedQuery { pub query: AppDataSelectQuery, pub mode: AppDataSelectMode, + pub cache: bool, } /// The data client is used to access an app's data storage capabilities. diff --git a/crates/l10n/Cargo.toml b/crates/l10n/Cargo.toml index c66d7d4..05d53f5 100644 --- a/crates/l10n/Cargo.toml +++ b/crates/l10n/Cargo.toml @@ -11,4 +11,4 @@ homepage.workspace = true [dependencies] pathbufd = "0.1.4" serde = { version = "1.0.219", features = ["derive"] } -toml = "0.9.4" +toml = "0.9.5" diff --git a/crates/shared/Cargo.toml b/crates/shared/Cargo.toml index 34311ac..4b72694 100644 --- a/crates/shared/Cargo.toml +++ b/crates/shared/Cargo.toml @@ -17,4 +17,4 @@ regex = "1.11.1" serde = { version = "1.0.219", features = ["derive"] } sha2 = "0.10.9" snowflaked = "1.0.3" -uuid = { version = "1.17.0", features = ["v4"] } +uuid = { version = "1.18.0", features = ["v4"] }