Skip to content

Commit

Permalink
Use multiple caches
Browse files Browse the repository at this point in the history
- set up a 5-minute memory cache
- use a back-up 24-hour db cache
  • Loading branch information
tudoramariei committed Oct 13, 2023
1 parent e739f70 commit b66e604
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
6 changes: 3 additions & 3 deletions api/buildings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import PIL.Image
from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.db import models
Expand All @@ -15,8 +14,9 @@
from django.utils.safestring import mark_safe
from django.utils.translation import get_language, gettext_lazy as _

from seismic_site.caching import delete_from_cache

BUILDINGS_LISTING_CACHE_KEY = "all_buildings_listing"
BUILDINGS_LISTING_CACHE_TIMEOUT = 60 * 60 * 24 # 24 hours


class SeismicCategoryChoice(Enum):
Expand Down Expand Up @@ -103,7 +103,7 @@ def bulk_create(self, *args, **kwargs):
super().bulk_create(self, *args, **kwargs)

Statistic.update_statistics()
cache.delete(BUILDINGS_LISTING_CACHE_KEY)
delete_from_cache(BUILDINGS_LISTING_CACHE_KEY)


class ApprovedBuilding(models.Manager):
Expand Down
4 changes: 2 additions & 2 deletions api/buildings/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver

from seismic_site.caching import delete_from_cache
from .models import BUILDINGS_LISTING_CACHE_KEY, Building, Statistic


Expand All @@ -10,7 +10,7 @@ def refresh_cache(instance: Building, **kwargs):
if not isinstance(instance, Building):
return

cache.delete(BUILDINGS_LISTING_CACHE_KEY)
delete_from_cache(BUILDINGS_LISTING_CACHE_KEY)


@receiver(post_save, sender=Building)
Expand Down
12 changes: 4 additions & 8 deletions api/buildings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

from django.conf import settings
from django.contrib.postgres.search import TrigramSimilarity
from django.core.cache import cache
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import permissions, status, viewsets
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.throttling import AnonRateThrottle

from seismic_site.caching import get_from_cache, set_to_cache
from .models import (
BUILDINGS_LISTING_CACHE_KEY,
BUILDINGS_LISTING_CACHE_TIMEOUT,
Building,
BuildingProximalUtilities,
BuildingWorkPerformed,
Expand Down Expand Up @@ -49,7 +48,7 @@ def list(self, request, *args, **kwargs):
"""
nonexistent = object() # sentinel

cached_data: List = cache.get(BUILDINGS_LISTING_CACHE_KEY, nonexistent)
cached_data: List = get_from_cache(BUILDINGS_LISTING_CACHE_KEY, nonexistent)

if cached_data is nonexistent:
queryset = self.filter_queryset(self.get_queryset())
Expand All @@ -62,7 +61,7 @@ def list(self, request, *args, **kwargs):
serializer = self.get_serializer(queryset, many=True)
cached_data = serializer.data

cache.set(BUILDINGS_LISTING_CACHE_KEY, cached_data, timeout=BUILDINGS_LISTING_CACHE_TIMEOUT)
set_to_cache(BUILDINGS_LISTING_CACHE_KEY, cached_data)

return Response(cached_data)

Expand Down Expand Up @@ -145,10 +144,7 @@ class WorkPerformedViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = WorkPerformedSerializer


@extend_schema(
request=StatisticSerializer,
responses=None # TODO: is it really None?
)
@extend_schema(request=StatisticSerializer, responses=None) # TODO: is it really None?
@api_view(["GET"])
@permission_classes((permissions.AllowAny,))
def statistics(request):
Expand Down
24 changes: 24 additions & 0 deletions api/seismic_site/caching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import Any

from django.core.cache import caches


def get_from_cache(data_key: str, default: Any = object()) -> Any:
cached_data = caches["memory"].get(data_key, default)

if cached_data is default:
cached_data = caches["default"].get(data_key, default)
if cached_data is not default:
caches["memory"].set(data_key, cached_data)

return cached_data


def set_to_cache(data_key: str, data: Any, timeout: int = None) -> None:
for cache in caches.all():
cache.set(data_key, data, timeout=timeout)


def delete_from_cache(data_key: str) -> None:
for cache in caches.all():
cache.delete(data_key)
8 changes: 7 additions & 1 deletion api/seismic_site/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,15 @@

CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
"LOCATION": "seismic_cache_table",
"TIMEOUT": 60 * 60 * 24, # 24 hours
},
"memory": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "unique-snowflake",
}
"TIMEOUT": 60 * 5, # 5 minutes
},
}

# Internationalization
Expand Down

0 comments on commit b66e604

Please sign in to comment.