Add cachify decorator.

This commit is contained in:
Steve Howell 2017-10-30 16:31:47 -07:00 committed by Tim Abbott
parent 7e4702c9c1
commit 5be13fb066
2 changed files with 80 additions and 2 deletions

View File

@ -30,7 +30,7 @@ import logging
from io import BytesIO
from six.moves import zip, urllib
from typing import Union, Any, Callable, Sequence, Dict, Optional, TypeVar, Text, cast
from typing import Union, Any, Callable, Sequence, Dict, Optional, TypeVar, Text, Tuple, cast
from zerver.lib.str_utils import force_bytes
from zerver.lib.logging_util import create_logger
@ -74,6 +74,20 @@ def asynchronous(method):
wrapper.csrf_exempt = True # type: ignore # https://github.com/JukkaL/mypy/issues/1170
return wrapper
def cachify(method):
# type: (Callable) -> Callable
dct = {} # type: Dict[Tuple, Any]
def cache_wrapper(*args):
# type: (*Any) -> Any
tup = tuple(args)
if tup in dct:
return dct[tup]
result = method(*args)
dct[tup] = result
return result
return cache_wrapper
def update_user_activity(request, user_profile, query):
# type: (HttpRequest, UserProfile, Optional[str]) -> None
# update_active_status also pushes to rabbitmq, and it seems

View File

@ -29,7 +29,7 @@ from zerver.lib.request import \
RequestVariableConversionError
from zerver.decorator import (
api_key_only_webhook_view,
authenticate_notify,
authenticate_notify, cachify,
get_client_name, internal_notify_view, is_local_addr,
rate_limit, validate_api_key, logged_in_and_active,
return_success_on_head_request
@ -1255,6 +1255,70 @@ class RestAPITest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(result["Location"].endswith("/login/?next=/json/users"))
class CacheTestCase(ZulipTestCase):
def test_cachify_basics(self):
# type: () -> None
@cachify
def add(w, x, y, z):
# type: (Any, Any, Any, Any) -> Any
return w + x + y + z
for i in range(2):
self.assertEqual(add(1, 2, 4, 8), 15)
self.assertEqual(add('a', 'b', 'c', 'd'), 'abcd')
def test_cachify_is_per_call(self):
# type: () -> None
def test_greetings(greeting):
# type: (Text) -> Tuple[List[Text], List[Text]]
result_log = [] # type: List[Text]
work_log = [] # type: List[Text]
@cachify
def greet(first_name, last_name):
# type: (Text, Text) -> Text
msg = '%s %s %s' % (greeting, first_name, last_name)
work_log.append(msg)
return msg
result_log.append(greet('alice', 'smith'))
result_log.append(greet('bob', 'barker'))
result_log.append(greet('alice', 'smith'))
result_log.append(greet('cal', 'johnson'))
return (work_log, result_log)
work_log, result_log = test_greetings('hello')
self.assertEqual(work_log, [
'hello alice smith',
'hello bob barker',
'hello cal johnson',
])
self.assertEqual(result_log, [
'hello alice smith',
'hello bob barker',
'hello alice smith',
'hello cal johnson',
])
work_log, result_log = test_greetings('goodbye')
self.assertEqual(work_log, [
'goodbye alice smith',
'goodbye bob barker',
'goodbye cal johnson',
])
self.assertEqual(result_log, [
'goodbye alice smith',
'goodbye bob barker',
'goodbye alice smith',
'goodbye cal johnson',
])
class TestUserAgentParsing(ZulipTestCase):
def test_user_agent_parsing(self):
# type: () -> None