A Wrapped / Replay like for teal.fm and rocksky.app (currently on hiatus)
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: cache mbz lookups

Mia d05ce46c 94b9990c

+48
+1
Cargo.lock
··· 1292 1292 "jacquard-lexicon", 1293 1293 "metrics", 1294 1294 "metrics-exporter-prometheus", 1295 + "mini-moka", 1295 1296 "r2d2", 1296 1297 "reqwest", 1297 1298 "serde",
+1
Cargo.toml
··· 21 21 jacquard-lexicon = "0.9.2" 22 22 metrics = "0.24.3" 23 23 metrics-exporter-prometheus = { version = "0.18.0", default-features = false, features = ["http-listener"] } 24 + mini-moka = { version = "0.10.3", features = ["sync"] } 24 25 r2d2 = "0.8" 25 26 reqwest = "0.12.24" 26 27 serde = { version = "1.0.228", features = ["derive"] }
+25
src/mbz/lookup_cache.rs
··· 1 + use super::MbzQueryRes; 2 + use mini_moka::sync::Cache; 3 + use std::time::Duration; 4 + 5 + pub struct LookupCache(Cache<String, MbzQueryRes>); 6 + 7 + impl LookupCache { 8 + pub fn new() -> Self { 9 + let cache = Cache::builder() 10 + .time_to_live(Duration::from_mins(30)) 11 + .build(); 12 + LookupCache(cache) 13 + } 14 + 15 + pub fn get(&self, key: String) -> Option<MbzQueryRes> { 16 + self.0.get(&key).map(|mut res| { 17 + res.debug = String::default(); 18 + res 19 + }) 20 + } 21 + 22 + pub fn insert(&self, key: String, res: MbzQueryRes) { 23 + self.0.insert(key, res); 24 + } 25 + }
+21
src/mbz/mod.rs
··· 1 1 use duckdb::{Connection, params}; 2 + use std::sync::LazyLock; 2 3 4 + mod lookup_cache; 3 5 mod query; 4 6 mod replica; 5 7 6 8 pub use replica::ReplicationAgent; 7 9 pub use query::{FindMbzData, MbzQueryRes}; 8 10 11 + static CACHE: LazyLock<lookup_cache::LookupCache> = LazyLock::new(lookup_cache::LookupCache::new); 12 + 9 13 pub fn try_find_mbz_data( 10 14 conn: &Connection, 11 15 opts: &FindMbzData, 12 16 ) -> duckdb::Result<Option<MbzQueryRes>> { 17 + if let Some(entry) = CACHE.get(build_cache_key(opts)) { 18 + return Ok(Some(entry)); 19 + } 20 + 13 21 let mut rows = query::find_mbz_data(conn, opts)?; 14 22 if !rows.is_empty() { 15 23 let row = rows.pop(); 24 + 25 + if let Some(row) = &row { 26 + CACHE.insert(build_cache_key(opts), row.clone()); 27 + } 28 + 16 29 return Ok(row); 17 30 } 18 31 ··· 20 33 21 34 Ok(None) 22 35 } 36 + 37 + fn build_cache_key(opts: &FindMbzData) -> String { 38 + let release = opts.release_mbid.or(opts.release_name).unwrap_or(""); 39 + let track = opts.isrc.or(opts.recording_mbid).unwrap_or(opts.track_name); 40 + let artist = opts.artist_name.unwrap_or(""); 41 + 42 + format!("{track}\0{release}\0{artist}") 43 + }