about summary refs log tree commit diff
path: root/users
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-05-14T22·55+0200
committertazjin <tazjin@tvl.su>2022-05-14T23·50+0000
commite3d09c3446b6a5ba7e7fafa66712b3420714e226 (patch)
tree88ed88d9edd1df0e2f50eb2dc3fc8237a3f3d58a /users
parent89f25b431d9447f7c2cf9781aba10418578ec68a (diff)
refactor(tazjin/tgsa): factor out cache access helper r/4075
factor out a function to access telegram posts from the cache,
fetching them anew if required.

a small behavioural change means that the program now takes a write
lock when fetching a post, to avoid simultaneously fetching the same
post many times (quite likely once it serves image redirects).

Change-Id: If9c1429f86fb118dab90834f349cb222709c3a31
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5608
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Diffstat (limited to 'users')
-rw-r--r--users/tazjin/tgsa/src/main.rs34
1 files changed, 21 insertions, 13 deletions
diff --git a/users/tazjin/tgsa/src/main.rs b/users/tazjin/tgsa/src/main.rs
index 28b5d4253aa4..911f1bad6788 100644
--- a/users/tazjin/tgsa/src/main.rs
+++ b/users/tazjin/tgsa/src/main.rs
@@ -188,34 +188,42 @@ fn to_bbcode(link: &TgLink, msg: &TgMessage) -> String {
 // cache everything for one hour
 const CACHE_EXPIRY: Duration = Duration::from_secs(60 * 60);
 
-struct CacheEntry {
+#[derive(Clone)]
+struct TgPost {
     bbcode: String,
     at: Instant,
 }
 
-type Cache = RwLock<HashMap<TgLink, CacheEntry>>;
+type Cache = RwLock<HashMap<TgLink, TgPost>>;
 
-fn handle_tg_link(cache: &Cache, link: &TgLink) -> Result<String> {
+fn fetch_with_cache(cache: &Cache, link: &TgLink) -> Result<TgPost> {
     if let Some(entry) = cache.read().unwrap().get(&link) {
         if Instant::now() - entry.at < CACHE_EXPIRY {
             println!("serving {}#{} from cache", link.username, link.message_id);
-            return Ok(entry.bbcode.to_string());
+            return Ok(entry.clone());
         }
     }
 
+    // limit concurrent fetching
+    // TODO(tazjin): per link?
+    let mut writer = cache.write().unwrap();
+
     let embed = fetch_embed(&link)?;
     let msg = parse_tgmessage(&embed)?;
-    let bbcode = to_bbcode(&link, &msg);
 
-    cache.write().unwrap().insert(
-        link.clone(),
-        CacheEntry {
-            bbcode: bbcode.clone(),
-            at: Instant::now(),
-        },
-    );
+    let post = TgPost {
+        bbcode: to_bbcode(&link, &msg),
+        at: Instant::now(),
+    };
+
+    writer.insert(link.clone(), post.clone());
 
-    Ok(bbcode)
+    Ok(post)
+}
+
+fn handle_tg_link(cache: &Cache, link: &TgLink) -> Result<String> {
+    let post = fetch_with_cache(cache, link)?;
+    Ok(post.bbcode)
 }
 
 fn main() {