about summary refs log tree commit diff
path: root/users
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-05-14T22·19+0200
committerclbot <clbot@tvl.fyi>2022-05-14T22·31+0000
commit89f25b431d9447f7c2cf9781aba10418578ec68a (patch)
treeef1bd369047a83f3030ab88f85c5c55c3f93a006 /users
parentaf31da8cfc9caee8c2cd44df5ee5c1ed3a9b3ed7 (diff)
feat(tazjin/tgsa): Expire cached telegram entries after one hour r/4074
Telegram expires certain links in messages after some (unknown) amount
of time; this commit is the first step to working around that by
providing an image URL proxy.

In order to do that, we tick two important boxes here:

1. Store an extensible data structure in the cache.
2. Expire them periodically.

Change-Id: Iba192d8b71db4493c942d1baf5680bd086f8f60b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5607
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'users')
-rw-r--r--users/tazjin/tgsa/src/main.rs27
1 files changed, 22 insertions, 5 deletions
diff --git a/users/tazjin/tgsa/src/main.rs b/users/tazjin/tgsa/src/main.rs
index 92ecc5572896..28b5d4253aa4 100644
--- a/users/tazjin/tgsa/src/main.rs
+++ b/users/tazjin/tgsa/src/main.rs
@@ -1,6 +1,7 @@
 use anyhow::{anyhow, Context, Result};
 use std::collections::HashMap;
 use std::sync::RwLock;
+use std::time::{Duration, Instant};
 
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
 struct TgLink {
@@ -184,19 +185,35 @@ fn to_bbcode(link: &TgLink, msg: &TgMessage) -> String {
     out
 }
 
-type Cache = RwLock<HashMap<TgLink, String>>;
+// cache everything for one hour
+const CACHE_EXPIRY: Duration = Duration::from_secs(60 * 60);
+
+struct CacheEntry {
+    bbcode: String,
+    at: Instant,
+}
+
+type Cache = RwLock<HashMap<TgLink, CacheEntry>>;
 
 fn handle_tg_link(cache: &Cache, link: &TgLink) -> Result<String> {
-    if let Some(bbcode) = cache.read().unwrap().get(&link) {
-        println!("serving {}#{} from cache", link.username, link.message_id);
-        return Ok(bbcode.to_string());
+    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());
+        }
     }
 
     let embed = fetch_embed(&link)?;
     let msg = parse_tgmessage(&embed)?;
     let bbcode = to_bbcode(&link, &msg);
 
-    cache.write().unwrap().insert(link.clone(), bbcode.clone());
+    cache.write().unwrap().insert(
+        link.clone(),
+        CacheEntry {
+            bbcode: bbcode.clone(),
+            at: Instant::now(),
+        },
+    );
 
     Ok(bbcode)
 }