From 507fa328ae04f91de10fc62223a1a4b43482213b Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Mon, 1 Jul 2019 20:59:49 +0200
Subject: [PATCH] Implement proper cache busting

---
 retribute_api/cache.py            | 20 +++++++++++++++++---
 retribute_api/search/consumers.py |  2 +-
 retribute_api/search/sources.py   |  1 -
 tests/search/test_consumers.py    |  2 +-
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/retribute_api/cache.py b/retribute_api/cache.py
index 13a52d2..0c6ba3d 100644
--- a/retribute_api/cache.py
+++ b/retribute_api/cache.py
@@ -46,9 +46,10 @@ class Noop(Backend):
 
 
 class Redis(Backend):
-    def __init__(self, params):
+    def __init__(self, params, write_only=False):
         self.params = params
         self._redis = None
+        self.write_only = write_only
 
     async def redis(self):
         if self._redis:
@@ -59,6 +60,8 @@ class Redis(Backend):
         return self._redis
 
     async def get(self, key):
+        if self.write_only:
+            raise self.NotFound(key)
         r = await self.redis()
         try:
             v = await r.get(key)
@@ -89,9 +92,20 @@ class Redis(Backend):
 _DEFAULT = None
 
 
-def get_default():
+_WRITE_ONLY_DEFAULT = None
+
+
+def get_write_only_default():
+    global _WRITE_ONLY_DEFAULT
+    if _WRITE_ONLY_DEFAULT:
+        return _WRITE_ONLY_DEFAULT
+    _WRITE_ONLY_DEFAULT = Redis(settings.ASYNC_REDIS_PARAMS, write_only=True)
+    return _WRITE_ONLY_DEFAULT
+
+
+def get_default(**kwargs):
     global _DEFAULT
     if _DEFAULT:
         return _DEFAULT
-    _DEFAULT = Redis(settings.ASYNC_REDIS_PARAMS)
+    _DEFAULT = Redis(settings.ASYNC_REDIS_PARAMS, **kwargs)
     return _DEFAULT
diff --git a/retribute_api/search/consumers.py b/retribute_api/search/consumers.py
index 9b18f37..9627e9a 100644
--- a/retribute_api/search/consumers.py
+++ b/retribute_api/search/consumers.py
@@ -98,7 +98,7 @@ class SearchSingleConsumer(AsyncHttpConsumer):
             self.scope["query_string"].decode(), keep_blank_values=True
         )
         if "nocache" in params:
-            c = cache.Noop()
+            c = cache.get_write_only_default()
         else:
             c = cache.get_default()
         try:
diff --git a/retribute_api/search/sources.py b/retribute_api/search/sources.py
index aea4fd3..f33528a 100644
--- a/retribute_api/search/sources.py
+++ b/retribute_api/search/sources.py
@@ -44,7 +44,6 @@ class Activitypub(Source):
     ]
 
     async def get(self, lookup, session, cache):
-
         try:
             actor_data = await cache.get("activitypub:profile:{}".format(lookup))
         except cache.NotFound:
diff --git a/tests/search/test_consumers.py b/tests/search/test_consumers.py
index 1ecba9f..ae3b67f 100644
--- a/tests/search/test_consumers.py
+++ b/tests/search/test_consumers.py
@@ -72,7 +72,7 @@ async def test_search_consumer_no_cache(
     )
     response = await communicator.get_response()
     assert get.call_args[0][0] == "test@user.domain"
-    assert isinstance(get.call_args[1]["cache"], cache.Noop)
+    assert get.call_args[1]["cache"].write_only is True
     get_profile.assert_called_once_with(
         "webfinger", "test@user.domain", get.return_value
     )
-- 
GitLab