feat: cache package search results with Redis

The queries being done on the package search page are quite costly.
(Especially the default one ordered by "Popularity" when navigating to /packages)

Let's add the search results to the Redis cache:
Every result of a search query is being pushed to Redis until we hit our maximum of 50k.
An entry expires after 3 minutes before it's evicted from the cache.
Lifetime an Max values are configurable.

Signed-off-by: moson-mo <mo-son@mailbox.org>
This commit is contained in:
moson-mo 2023-07-02 01:06:34 +02:00
parent 7c8b9ba6bc
commit 3acfb08a0f
No known key found for this signature in database
GPG key ID: 4A4760AB4EE15296
8 changed files with 173 additions and 74 deletions

View file

@ -5,7 +5,7 @@ from unittest import mock
import pytest
from fastapi.testclient import TestClient
from aurweb import asgi, config, db, time
from aurweb import asgi, cache, config, db, time
from aurweb.filters import datetime_display
from aurweb.models import License, PackageLicense
from aurweb.models.account_type import USER_ID, AccountType
@ -63,6 +63,11 @@ def setup(db_test):
return
@pytest.fixture(autouse=True)
def clear_fakeredis_cache():
cache._redis.flushall()
@pytest.fixture
def client() -> TestClient:
"""Yield a FastAPI TestClient."""
@ -815,6 +820,8 @@ def test_packages_search_by_keywords(client: TestClient, packages: list[Package]
# And request packages with that keyword, we should get 1 result.
with client as request:
# clear fakeredis cache
cache._redis.flushall()
response = request.get("/packages", params={"SeB": "k", "K": "testKeyword"})
assert response.status_code == int(HTTPStatus.OK)
@ -870,6 +877,8 @@ def test_packages_search_by_maintainer(
# This time, we should get `package` returned, since it's now an orphan.
with client as request:
# clear fakeredis cache
cache._redis.flushall()
response = request.get("/packages", params={"SeB": "m"})
assert response.status_code == int(HTTPStatus.OK)
root = parse_root(response.text)
@ -902,6 +911,8 @@ def test_packages_search_by_comaintainer(
# Then test that it's returned by our search.
with client as request:
# clear fakeredis cache
cache._redis.flushall()
response = request.get(
"/packages", params={"SeB": "c", "K": maintainer.Username}
)