From 7ec7f92812a4693876754575e72794e9010e0391 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 20 Oct 2023 20:31:48 +0200 Subject: fix(users/Profpatsch/openlab-tools): return 304 iff cache is same MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Profpatsch Tested-by: BuildkiteCI --- users/Profpatsch/openlab-tools/src/OpenlabTools.hs | 20 ++++++++++++++------ 1 file 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 -- cgit 1.4.1