My personal site cherry.computer
htmx tailwind axum askama

feat: cache scraped Backloggd result

cherry.computer 0a3ff8e2 e9a32743

verified
+215 -6
+202
server/Cargo.lock
··· 18 18 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 19 20 20 [[package]] 21 + name = "ahash" 22 + version = "0.8.12" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" 25 + dependencies = [ 26 + "cfg-if", 27 + "once_cell", 28 + "version_check", 29 + "zerocopy", 30 + ] 31 + 32 + [[package]] 21 33 name = "alloc-no-stdlib" 22 34 version = "2.0.4" 23 35 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 31 43 dependencies = [ 32 44 "alloc-no-stdlib", 33 45 ] 46 + 47 + [[package]] 48 + name = "allocator-api2" 49 + version = "0.2.21" 50 + source = "registry+https://github.com/rust-lang/crates.io-index" 51 + checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 34 52 35 53 [[package]] 36 54 name = "anyhow" ··· 96 114 "tokio", 97 115 "zstd", 98 116 "zstd-safe", 117 + ] 118 + 119 + [[package]] 120 + name = "async-trait" 121 + version = "0.1.89" 122 + source = "registry+https://github.com/rust-lang/crates.io-index" 123 + checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" 124 + dependencies = [ 125 + "proc-macro2", 126 + "quote", 127 + "syn", 99 128 ] 100 129 101 130 [[package]] ··· 240 269 checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 241 270 242 271 [[package]] 272 + name = "cached" 273 + version = "0.56.0" 274 + source = "registry+https://github.com/rust-lang/crates.io-index" 275 + checksum = "801927ee168e17809ab8901d9f01f700cd7d8d6a6527997fee44e4b0327a253c" 276 + dependencies = [ 277 + "ahash", 278 + "async-trait", 279 + "cached_proc_macro", 280 + "cached_proc_macro_types", 281 + "futures", 282 + "hashbrown", 283 + "once_cell", 284 + "thiserror", 285 + "tokio", 286 + "web-time", 287 + ] 288 + 289 + [[package]] 290 + name = "cached_proc_macro" 291 + version = "0.25.0" 292 + source = "registry+https://github.com/rust-lang/crates.io-index" 293 + checksum = "9225bdcf4e4a9a4c08bf16607908eb2fbf746828d5e0b5e019726dbf6571f201" 294 + dependencies = [ 295 + "darling", 296 + "proc-macro2", 297 + "quote", 298 + "syn", 299 + ] 300 + 301 + [[package]] 302 + name = "cached_proc_macro_types" 303 + version = "0.1.1" 304 + source = "registry+https://github.com/rust-lang/crates.io-index" 305 + checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" 306 + 307 + [[package]] 243 308 name = "cc" 244 309 version = "1.2.34" 245 310 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 327 392 ] 328 393 329 394 [[package]] 395 + name = "darling" 396 + version = "0.20.11" 397 + source = "registry+https://github.com/rust-lang/crates.io-index" 398 + checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 399 + dependencies = [ 400 + "darling_core", 401 + "darling_macro", 402 + ] 403 + 404 + [[package]] 405 + name = "darling_core" 406 + version = "0.20.11" 407 + source = "registry+https://github.com/rust-lang/crates.io-index" 408 + checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 409 + dependencies = [ 410 + "fnv", 411 + "ident_case", 412 + "proc-macro2", 413 + "quote", 414 + "strsim", 415 + "syn", 416 + ] 417 + 418 + [[package]] 419 + name = "darling_macro" 420 + version = "0.20.11" 421 + source = "registry+https://github.com/rust-lang/crates.io-index" 422 + checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 423 + dependencies = [ 424 + "darling_core", 425 + "quote", 426 + "syn", 427 + ] 428 + 429 + [[package]] 330 430 name = "derive_more" 331 431 version = "2.0.1" 332 432 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 426 526 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 427 527 428 528 [[package]] 529 + name = "foldhash" 530 + version = "0.1.5" 531 + source = "registry+https://github.com/rust-lang/crates.io-index" 532 + checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 533 + 534 + [[package]] 429 535 name = "foreign-types" 430 536 version = "0.3.2" 431 537 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 460 566 ] 461 567 462 568 [[package]] 569 + name = "futures" 570 + version = "0.3.31" 571 + source = "registry+https://github.com/rust-lang/crates.io-index" 572 + checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 573 + dependencies = [ 574 + "futures-channel", 575 + "futures-core", 576 + "futures-io", 577 + "futures-sink", 578 + "futures-task", 579 + "futures-util", 580 + ] 581 + 582 + [[package]] 463 583 name = "futures-channel" 464 584 version = "0.3.31" 465 585 source = "registry+https://github.com/rust-lang/crates.io-index" 466 586 checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 467 587 dependencies = [ 468 588 "futures-core", 589 + "futures-sink", 469 590 ] 470 591 471 592 [[package]] ··· 473 594 version = "0.3.31" 474 595 source = "registry+https://github.com/rust-lang/crates.io-index" 475 596 checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 597 + 598 + [[package]] 599 + name = "futures-io" 600 + version = "0.3.31" 601 + source = "registry+https://github.com/rust-lang/crates.io-index" 602 + checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 476 603 477 604 [[package]] 478 605 name = "futures-sink" ··· 493 620 checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 494 621 dependencies = [ 495 622 "futures-core", 623 + "futures-sink", 496 624 "futures-task", 497 625 "pin-project-lite", 498 626 "pin-utils", ··· 569 697 version = "0.15.5" 570 698 source = "registry+https://github.com/rust-lang/crates.io-index" 571 699 checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" 700 + dependencies = [ 701 + "allocator-api2", 702 + "equivalent", 703 + "foldhash", 704 + ] 572 705 573 706 [[package]] 574 707 name = "html5ever" ··· 801 934 ] 802 935 803 936 [[package]] 937 + name = "ident_case" 938 + version = "1.0.1" 939 + source = "registry+https://github.com/rust-lang/crates.io-index" 940 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 941 + 942 + [[package]] 804 943 name = "idna" 805 944 version = "1.1.0" 806 945 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1007 1146 "anyhow", 1008 1147 "askama", 1009 1148 "axum", 1149 + "cached", 1010 1150 "reqwest", 1011 1151 "scraper", 1012 1152 "tokio", ··· 1619 1759 ] 1620 1760 1621 1761 [[package]] 1762 + name = "strsim" 1763 + version = "0.11.1" 1764 + source = "registry+https://github.com/rust-lang/crates.io-index" 1765 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1766 + 1767 + [[package]] 1622 1768 name = "subtle" 1623 1769 version = "2.6.1" 1624 1770 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1701 1847 ] 1702 1848 1703 1849 [[package]] 1850 + name = "thiserror" 1851 + version = "2.0.16" 1852 + source = "registry+https://github.com/rust-lang/crates.io-index" 1853 + checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" 1854 + dependencies = [ 1855 + "thiserror-impl", 1856 + ] 1857 + 1858 + [[package]] 1859 + name = "thiserror-impl" 1860 + version = "2.0.16" 1861 + source = "registry+https://github.com/rust-lang/crates.io-index" 1862 + checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" 1863 + dependencies = [ 1864 + "proc-macro2", 1865 + "quote", 1866 + "syn", 1867 + ] 1868 + 1869 + [[package]] 1704 1870 name = "thread_local" 1705 1871 version = "1.1.9" 1706 1872 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1965 2131 checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1966 2132 1967 2133 [[package]] 2134 + name = "version_check" 2135 + version = "0.9.5" 2136 + source = "registry+https://github.com/rust-lang/crates.io-index" 2137 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2138 + 2139 + [[package]] 1968 2140 name = "want" 1969 2141 version = "0.3.1" 1970 2142 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2070 2242 ] 2071 2243 2072 2244 [[package]] 2245 + name = "web-time" 2246 + version = "1.1.0" 2247 + source = "registry+https://github.com/rust-lang/crates.io-index" 2248 + checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2249 + dependencies = [ 2250 + "js-sys", 2251 + "wasm-bindgen", 2252 + ] 2253 + 2254 + [[package]] 2073 2255 name = "web_atoms" 2074 2256 version = "0.1.3" 2075 2257 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2266 2448 "quote", 2267 2449 "syn", 2268 2450 "synstructure", 2451 + ] 2452 + 2453 + [[package]] 2454 + name = "zerocopy" 2455 + version = "0.8.26" 2456 + source = "registry+https://github.com/rust-lang/crates.io-index" 2457 + checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" 2458 + dependencies = [ 2459 + "zerocopy-derive", 2460 + ] 2461 + 2462 + [[package]] 2463 + name = "zerocopy-derive" 2464 + version = "0.8.26" 2465 + source = "registry+https://github.com/rust-lang/crates.io-index" 2466 + checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" 2467 + dependencies = [ 2468 + "proc-macro2", 2469 + "quote", 2470 + "syn", 2269 2471 ] 2270 2472 2271 2473 [[package]]
+1
server/Cargo.toml
··· 9 9 anyhow = "1.0.57" 10 10 askama = "0.14.0" 11 11 axum = "0.8.1" 12 + cached = { version = "0.56.0", features = ["async"] } 12 13 reqwest = "0.12.23" 13 14 scraper = "0.24.0" 14 15 tokio = { version = "1.18.2", features = ["full"] }
+2 -5
server/src/index.rs
··· 1 - use crate::scrapers::backloggd::Backloggd; 1 + use crate::scrapers::backloggd::{self, Backloggd}; 2 2 3 3 use askama::Template; 4 4 ··· 11 11 impl RootTemplate { 12 12 pub async fn new() -> RootTemplate { 13 13 RootTemplate { 14 - game: Backloggd::fetch() 15 - .await 16 - .map_err(|error| tracing::warn!(%error, "failed to scrape Backloggd")) 17 - .ok(), 14 + game: backloggd::cached_fetch().await, 18 15 } 19 16 } 20 17 }
+10 -1
server/src/scrapers/backloggd.rs
··· 1 - use std::sync::LazyLock; 1 + use std::{sync::LazyLock, time::Duration}; 2 2 3 3 use anyhow::Context; 4 + use cached::proc_macro::once; 4 5 use scraper::{Html, Selector}; 5 6 6 7 #[derive(Debug, Clone)] ··· 49 50 Ok(Self { name, image }) 50 51 } 51 52 } 53 + 54 + #[once(time = 300, option = false)] 55 + pub async fn cached_fetch() -> Option<Backloggd> { 56 + Backloggd::fetch() 57 + .await 58 + .map_err(|error| tracing::warn!(?error, "failed to scrape Backloggd")) 59 + .ok() 60 + }