zulip/zerver/views/development/cache.py

24 lines
777 B
Python
Raw Normal View History

import os
from django.http import HttpRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from zerver.decorator import require_post
from zerver.lib.cache import get_cache_backend
per-request caches: Add per_request_cache library. We have historically cached two types of values on a per-request basis inside of memory: * linkifiers * display recipients Both of these caches were hand-written, and they both actually cache values that are also in memcached, so the per-request cache essentially only saves us from a few memcached hits. I think the linkifier per-request cache is a necessary evil. It's an important part of message rendering, and it's not super easy to structure the code to just get a single value up front and pass it down the stack. I'm not so sure we even need the display recipient per-request cache any more, as we are generally pretty smart now about hydrating recipient data in terms of how the code is organized. But I haven't done thorough research on that hypotheseis. Fortunately, it's not rocket science to just write a glorified memoize decorator and tie it into key places in the code: * middleware * tests (e.g. asserting db counts) * queue processors That's what I did in this commit. This commit definitely reduces the amount of code to maintain. I think it also gets us closer to possibly phasing out this whole technique, but that effort is beyond the scope of this PR. We could add some instrumentation to the decorator to see how often we get a non-trivial number of saved round trips to memcached. Note that when we flush linkifiers, we just use a big hammer and flush the entire per-request cache for linkifiers, since there is only ever one realm in the cache.
2023-07-14 19:46:50 +02:00
from zerver.lib.per_request_cache import flush_per_request_caches
from zerver.lib.response import json_success
from zerver.models.clients import clear_client_cache
ZULIP_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../")
# This is used only by the Puppeteer tests to clear all the cache after each run.
@csrf_exempt
@require_post
def remove_caches(request: HttpRequest) -> HttpResponse: # nocoverage
cache = get_cache_backend(None)
cache.clear()
clear_client_cache()
flush_per_request_caches()
return json_success(request)