From d1cb2187c1a74b394df651cb244cbf93982493cb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sun, 2 Apr 2023 17:01:51 +0300 Subject: [PATCH] add cache b4tman/qchgk_web#1 using moka --- Cargo.lock | 363 +++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + src/main.rs | 57 +++++++-- 3 files changed, 410 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73f81cc..51e630a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,6 +210,12 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "byteorder" version = "1.4.3" @@ -237,6 +243,37 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "camino" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.0.79" @@ -370,6 +407,29 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-utils" version = "0.8.15" @@ -537,6 +597,27 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +[[package]] +name = "errno" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-chain" version = "0.12.4" @@ -547,6 +628,15 @@ dependencies = [ "version_check 0.9.4", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "filetime" version = "0.2.20" @@ -555,7 +645,7 @@ checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "windows-sys", ] @@ -689,6 +779,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hkdf" version = "0.10.0" @@ -745,7 +841,7 @@ dependencies = [ "time 0.1.45", "traitobject", "typeable", - "unicase", + "unicase 1.4.2", "url", ] @@ -814,6 +910,26 @@ dependencies = [ "libc", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys", +] + [[package]] name = "iovec" version = "0.1.4" @@ -939,6 +1055,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" + [[package]] name = "lmdb-zero" version = "0.4.4" @@ -951,6 +1073,16 @@ dependencies = [ "supercow", ] +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.3.9" @@ -969,6 +1101,15 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "matches" version = "0.1.10" @@ -991,6 +1132,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.2.6" @@ -1052,6 +1202,29 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "moka" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ccedbe530334b20d6f57b2ca9f7c54c7bd1072a5a0b0035970aafd53982bd8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "num_cpus", + "once_cell", + "parking_lot", + "quanta", + "rustc_version", + "scheduled-thread-pool", + "skeptic", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "net2" version = "0.2.38" @@ -1141,6 +1314,29 @@ dependencies = [ "serde", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys", +] + [[package]] name = "password-hash" version = "0.3.2" @@ -1283,11 +1479,23 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase 2.6.0", +] + [[package]] name = "qchgk_web" version = "0.1.1" dependencies = [ "chgk_ledb_lib", + "moka", "rand", "rocket", "rocket_contrib", @@ -1295,6 +1503,22 @@ dependencies = [ "serde_json", ] +[[package]] +name = "quanta" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27" +dependencies = [ + "crossbeam-utils", + "libc", + "mach", + "once_cell", + "raw-cpuid", + "wasi 0.10.0+wasi-snapshot-preview1", + "web-sys", + "winapi 0.3.9", +] + [[package]] name = "quote" version = "0.6.13" @@ -1343,6 +1567,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1352,6 +1585,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -1359,7 +1601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -1465,6 +1707,29 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.13" @@ -1486,12 +1751,36 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "scratch" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +dependencies = [ + "serde", +] + [[package]] name = "serde" version = "1.0.159" @@ -1568,6 +1857,21 @@ dependencies = [ "digest 0.10.6", ] +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob 0.3.1", + "pulldown-cmark", + "tempfile", + "walkdir", +] + [[package]] name = "slab" version = "0.4.8" @@ -1643,6 +1947,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys", +] + [[package]] name = "tera" version = "0.11.20" @@ -1761,6 +2084,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +[[package]] +name = "triomphe" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" + [[package]] name = "typeable" version = "0.1.2" @@ -1838,6 +2167,15 @@ dependencies = [ "version_check 0.1.5", ] +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check 0.9.4", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -1892,6 +2230,15 @@ dependencies = [ "percent-encoding 1.0.1", ] +[[package]] +name = "uuid" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" +dependencies = [ + "getrandom", +] + [[package]] name = "version_check" version = "0.1.5" @@ -1986,6 +2333,16 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index ded3553..64e3809 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ serde="1.0" serde_json="1.0" rocket="0.4" chgk_ledb_lib = {git = "https://gitea.b4tman.ru/b4tman/chgk_ledb.git", rev="8120a996a3", package="chgk_ledb_lib"} +moka = "0.10.1" [dependencies.rocket_contrib] version = "0.4" diff --git a/src/main.rs b/src/main.rs index bedb496..5d9891b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,11 +15,15 @@ use rocket_contrib::templates::Template; use rand::distributions::Uniform; use rand::Rng; +use std::ops::Deref; use std::sync::Arc; use chgk_ledb_lib::db; use chgk_ledb_lib::questions::Question; +use moka::sync::Cache; +use std::time::Duration; + const DB_FILENAME: &str = "db.dat"; trait ErrorEmpty { @@ -34,9 +38,27 @@ impl ErrorEmpty for Result { } } +#[derive(Clone)] +struct ArcTemplateData { + value: Arc, +} + +impl ArcTemplateData { + fn new(value: serde_json::Value) -> ArcTemplateData { + ArcTemplateData { + value: Arc::new(value), + } + } + fn render(&self, name: &'static str) -> Template { + Template::render(name, self.value.deref()) + } +} + +type TemplateCache = moka::sync::Cache; + type DataBaseInner = db::Reader; type DataBase = Arc; -struct AppState{ +struct AppState { db: DataBase, database_distribution: Uniform, } @@ -49,7 +71,7 @@ impl From for AppState { Self { db, - database_distribution + database_distribution, } } } @@ -63,7 +85,16 @@ fn get_question(db: &DataBase, id: usize) -> Result { db.get(id - 1).err_empty() } -fn show_question_details(template_name: &'static str, data: &AppState, id: usize) -> Template { +fn show_question_details( + template_name: &'static str, + data: &AppState, + cache: &TemplateCache, + id: usize, +) -> Template { + if let Some(value) = cache.get(&id) { + return value.render(template_name); + } + match get_question(&data.db, id) { Ok(question) => { let mut context = serde_json::to_value(question).expect("question serialize"); @@ -71,7 +102,12 @@ fn show_question_details(template_name: &'static str, data: &AppState, id: usize let next_id = random_question_id(&data.database_distribution); context["next"] = serde_json::to_value(next_id).expect("question id serialize"); } - Template::render(template_name, &context) + + let value = ArcTemplateData::new(context); + let result = value.render(template_name); + cache.insert(id, value); + + result } Err(_) => { use std::collections::HashMap; @@ -82,13 +118,13 @@ fn show_question_details(template_name: &'static str, data: &AppState, id: usize } #[get("/q/")] -fn show_question(data: State, id: usize) -> Template { - show_question_details("question", data.inner(), id) +fn show_question(data: State, cache: State, id: usize) -> Template { + show_question_details("question", data.inner(), cache.inner(), id) } #[get("/q//a")] -fn show_answer(data: State, id: usize) -> Template { - show_question_details("answer", data.inner(), id) +fn show_answer(data: State, cache: State, id: usize) -> Template { + show_question_details("answer", data.inner(), cache.inner(), id) } #[get("/q/0")] @@ -116,9 +152,14 @@ fn not_found(_req: &rocket::Request) -> Template { fn rocket() -> Rocket { let state: AppState = db::Reader::new(DB_FILENAME, 2048).expect("open db").into(); + let cache: TemplateCache = Cache::builder() + .time_to_idle(Duration::from_secs(15 * 60)) + .max_capacity(300) + .build(); rocket::ignite() .manage(state) + .manage(cache) .register(catchers![not_found]) .mount( "/",