mirror of
https://github.com/GSA/notifications-api.git
synced 2026-05-05 16:48:31 -04:00
Cache serialised template in memory
This commit is contained in:
@@ -1,7 +1,31 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from collections import defaultdict
|
||||||
|
from functools import partial
|
||||||
|
from threading import RLock
|
||||||
|
|
||||||
|
import cachetools
|
||||||
|
|
||||||
from app.dao import templates_dao
|
from app.dao import templates_dao
|
||||||
|
|
||||||
|
caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
|
||||||
|
locks = defaultdict(RLock)
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
class SerialisedModel(ABC):
|
||||||
|
|
||||||
@@ -40,6 +64,7 @@ class SerialisedTemplate(SerialisedModel):
|
|||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@memory_cache
|
||||||
def from_id_and_service_id(cls, template_id, service_id):
|
def from_id_and_service_id(cls, template_id, service_id):
|
||||||
return cls(cls.get_dict(template_id, service_id))
|
return cls(cls.get_dict(template_id, service_id))
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import pytest
|
|||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
from boto.exception import SQSError
|
from boto.exception import SQSError
|
||||||
|
|
||||||
|
from app.dao import templates_dao
|
||||||
from app.dao.service_sms_sender_dao import dao_update_service_sms_sender
|
from app.dao.service_sms_sender_dao import dao_update_service_sms_sender
|
||||||
from app.models import (
|
from app.models import (
|
||||||
ScheduledNotification,
|
ScheduledNotification,
|
||||||
@@ -211,6 +212,33 @@ def test_notification_reply_to_text_is_original_value_if_sender_is_changed_after
|
|||||||
assert notifications[0].reply_to_text == '123456'
|
assert notifications[0].reply_to_text == '123456'
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_cache_template_lookups_in_memory(mocker, client, sample_template):
|
||||||
|
|
||||||
|
mock_get_template = mocker.patch(
|
||||||
|
'app.dao.templates_dao.dao_get_template_by_id_and_service_id',
|
||||||
|
wraps=templates_dao.dao_get_template_by_id_and_service_id,
|
||||||
|
)
|
||||||
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'phone_number': '+447700900855',
|
||||||
|
'template_id': str(sample_template.id),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in range(5):
|
||||||
|
auth_header = create_authorization_header(service_id=sample_template.service_id)
|
||||||
|
client.post(
|
||||||
|
path='/v2/notifications/sms',
|
||||||
|
data=json.dumps(data),
|
||||||
|
headers=[('Content-Type', 'application/json'), auth_header]
|
||||||
|
)
|
||||||
|
|
||||||
|
assert mock_get_template.call_args_list == [
|
||||||
|
call(service_id=sample_template.service_id, template_id=str(sample_template.id))
|
||||||
|
]
|
||||||
|
assert Notification.query.count() == 5
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("notification_type, key_send_to, send_to",
|
@pytest.mark.parametrize("notification_type, key_send_to, send_to",
|
||||||
[("sms", "phone_number", "+447700900855"),
|
[("sms", "phone_number", "+447700900855"),
|
||||||
("email", "email_address", "sample@email.com")])
|
("email", "email_address", "sample@email.com")])
|
||||||
|
|||||||
Reference in New Issue
Block a user