about summary refs log tree commit diff
path: root/users/Profpatsch/openlab-tools/src
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2023-10-20T18·31+0200
committerclbot <clbot@tvl.fyi>2023-10-20T18·36+0000
commit7ec7f92812a4693876754575e72794e9010e0391 (patch)
tree933e4cedf6f8050a4f6464329399b7c0f7106c08 /users/Profpatsch/openlab-tools/src
parente5a44334fe09b1d9095908b37da15f48a681a0a9 (diff)
fix(users/Profpatsch/openlab-tools): return 304 iff cache is same r/6865
Now this is getting cool. After 5 minutes we will ask the backend
again (which takes like 3 seconds), but then we compare the old cached
result with the new result and only send it back to the client iff it
changed.

So the client will still have to wait for the roundtrip time, but
doesn’t have to pay for the content. Plus, it gets some info that
upstream hasn’t been updated.

Change-Id: I6dba40321949da5da6a16b2e799d939573c77ba7
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9811
Autosubmit: Profpatsch <mail@profpatsch.de>
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/Profpatsch/openlab-tools/src')
-rw-r--r--users/Profpatsch/openlab-tools/src/OpenlabTools.hs20
1 files changed, 14 insertions, 6 deletions
diff --git a/users/Profpatsch/openlab-tools/src/OpenlabTools.hs b/users/Profpatsch/openlab-tools/src/OpenlabTools.hs
index 20bacd582cc3..77ed0b04e769 100644
--- a/users/Profpatsch/openlab-tools/src/OpenlabTools.hs
+++ b/users/Profpatsch/openlab-tools/src/OpenlabTools.hs
@@ -350,18 +350,26 @@ newCache result = do
   let lastModified = until
   newTVarIO $ Cache {..}
 
-updateCache :: (NFData a) => SecondTime -> TVar (Cache a) -> a -> STM (Cache a)
+updateCache :: (NFData a, Eq a) => SecondTime -> TVar (Cache a) -> a -> STM (Cache a)
 updateCache now cache result' = do
   -- make sure we don’t hold onto the world by deepseq-ing and evaluating to WHNF
   let !result = deepseq result' result'
   let until = mkSecondTime $ (5 * 60) `addUTCTime` now.unSecondTime
-  let lastModified = now
-  let !updated = Cache {..}
-  _ <- writeTVar cache $! updated
-  pure updated
+  !toWrite <- do
+    old <- readTVar cache
+    -- only update the lastModified time iff the content changed (this is helpful for HTTP caching with If-Modified-Since)
+    if old.result == result
+      then do
+        let lastModified = old.lastModified
+        pure $ Cache {..}
+      else do
+        let lastModified = now
+        pure $ Cache {..}
+  _ <- writeTVar cache $! toWrite
+  pure toWrite
 
 -- | Run the given action iff the cache is stale, otherwise just return the item from the cache.
-updateCacheIfNewer :: (MonadUnliftIO m, NFData b) => SecondTime -> TVar (Cache b) -> m b -> m (Cache b)
+updateCacheIfNewer :: (MonadUnliftIO m, NFData b, Eq b) => SecondTime -> TVar (Cache b) -> m b -> m (Cache b)
 updateCacheIfNewer now cache act = withRunInIO $ \runInIO -> do
   old <- readTVarIO cache
   if old.until < now