Merge pull request #2891 from alphagov/cache-serialised-template

Cache serialised template in Redis and in memory
This commit is contained in:
Chris Hill-Scott
2020-06-23 14:18:01 +01:00
committed by GitHub
3 changed files with 139 additions and 1 deletions

View File

@@ -13,6 +13,7 @@ from marshmallow import (
post_dump
)
from marshmallow_sqlalchemy import field_for
from uuid import UUID
from notifications_utils.recipients import (
validate_email_address,
@@ -58,6 +59,14 @@ def _validate_datetime_not_in_past(dte, msg="Date cannot be in the past"):
raise ValidationError(msg)
class UUIDsAsStringsMixin:
@post_dump()
def __post_dump(self, data):
for key, value in data.items():
if isinstance(value, UUID):
data[key] = str(value)
class BaseSchema(ma.ModelSchema):
def __init__(self, load_json=False, *args, **kwargs):
@@ -341,7 +350,7 @@ class BaseTemplateSchema(BaseSchema):
strict = True
class TemplateSchema(BaseTemplateSchema):
class TemplateSchema(BaseTemplateSchema, UUIDsAsStringsMixin):
created_by_id = field_for(
models.Template, 'created_by_id', dump_to='created_by', dump_only=True

View File

@@ -1,7 +1,34 @@
from abc import ABC, abstractmethod
from collections import defaultdict
from functools import partial
from threading import RLock
import cachetools
from notifications_utils.clients.redis import RequestCache
from app import redis_store
from app.dao import templates_dao
caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
locks = defaultdict(RLock)
redis_cache = RequestCache(redis_store)
def memory_cache(func):
@cachetools.cached(
cache=caches[func.__qualname__],
lock=locks[func.__qualname__],
key=ignore_first_argument_cache_key,
)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def ignore_first_argument_cache_key(cls, *args, **kwargs):
return cachetools.keys.hashkey(*args, **kwargs)
class SerialisedModel(ABC):
@@ -40,10 +67,12 @@ class SerialisedTemplate(SerialisedModel):
}
@classmethod
@memory_cache
def from_id_and_service_id(cls, template_id, service_id):
return cls(cls.get_dict(template_id, service_id))
@staticmethod
@redis_cache.set('template-{template_id}-version-None')
def get_dict(template_id, service_id):
from app.schemas import template_schema